mirror of
https://git.joinplu.me/Plume/Plume.git
synced 2024-11-29 06:51:01 +00:00
Allow likes to be deleted with AP
This commit is contained in:
parent
bae49bcb47
commit
601fe7cf4f
7 changed files with 81 additions and 10 deletions
2
migrations/2018-05-12-213456_likes_add_ap_url/down.sql
Normal file
2
migrations/2018-05-12-213456_likes_add_ap_url/down.sql
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
-- This file should undo anything in `up.sql`
|
||||||
|
ALTER TABLE likes DROP COLUMN ap_url;
|
2
migrations/2018-05-12-213456_likes_add_ap_url/up.sql
Normal file
2
migrations/2018-05-12-213456_likes_add_ap_url/up.sql
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
-- Your SQL goes here
|
||||||
|
ALTER TABLE likes ADD COLUMN ap_url VARCHAR NOT NULL default '';
|
|
@ -210,12 +210,48 @@ impl Activity for Like {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_type(&self) -> String {
|
fn get_type(&self) -> String {
|
||||||
"Follow".to_string()
|
"Like".to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self) -> serde_json::Value {
|
fn serialize(&self) -> serde_json::Value {
|
||||||
json!({
|
json!({
|
||||||
"type": "Follow",
|
"type": "Like",
|
||||||
|
"id": self.id,
|
||||||
|
"actor": self.actor,
|
||||||
|
"object": self.object
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Undo {
|
||||||
|
id: String,
|
||||||
|
actor: serde_json::Value,
|
||||||
|
object: serde_json::Value
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Undo {
|
||||||
|
pub fn new<A: Actor, B: Object>(actor: &A, obj: &B, conn: &PgConnection) -> Undo {
|
||||||
|
Undo {
|
||||||
|
id: format!("{}/undo", obj.compute_id(conn)),
|
||||||
|
actor: serde_json::Value::String(actor.compute_id(conn)),
|
||||||
|
object: obj.serialize(conn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Activity for Undo {
|
||||||
|
fn get_id(&self) -> String {
|
||||||
|
self.id.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_type(&self) -> String {
|
||||||
|
"Undo".to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn serialize(&self) -> serde_json::Value {
|
||||||
|
json!({
|
||||||
|
"type": "Undo",
|
||||||
"id": self.id,
|
"id": self.id,
|
||||||
"actor": self.actor,
|
"actor": self.actor,
|
||||||
"object": self.object
|
"object": self.object
|
||||||
|
|
|
@ -64,9 +64,19 @@ pub trait Inbox: Actor + Sized {
|
||||||
let post = Post::get_by_ap_url(conn, act["object"].as_str().unwrap().to_string());
|
let post = Post::get_by_ap_url(conn, act["object"].as_str().unwrap().to_string());
|
||||||
Like::insert(conn, NewLike {
|
Like::insert(conn, NewLike {
|
||||||
post_id: post.unwrap().id,
|
post_id: post.unwrap().id,
|
||||||
user_id: liker.unwrap().id
|
user_id: liker.unwrap().id,
|
||||||
|
ap_url: act["id"].as_str().unwrap().to_string()
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
"Undo" => {
|
||||||
|
match act["object"]["type"].as_str().unwrap() {
|
||||||
|
"Like" => {
|
||||||
|
let like = Like::find_by_ap_url(conn, act["object"]["id"].as_str().unwrap().to_string()).unwrap();
|
||||||
|
like.delete(conn);
|
||||||
|
}
|
||||||
|
x => println!("Wanted to Undo a {}, but it is not supported yet", x)
|
||||||
|
}
|
||||||
|
},
|
||||||
x => println!("Received unknow activity type: {}", x)
|
x => println!("Received unknow activity type: {}", x)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,14 +13,16 @@ pub struct Like {
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
pub user_id: i32,
|
pub user_id: i32,
|
||||||
pub post_id: i32,
|
pub post_id: i32,
|
||||||
pub creation_date: chrono::NaiveDateTime
|
pub creation_date: chrono::NaiveDateTime,
|
||||||
|
pub ap_url: String
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Insertable)]
|
#[derive(Insertable)]
|
||||||
#[table_name = "likes"]
|
#[table_name = "likes"]
|
||||||
pub struct NewLike {
|
pub struct NewLike {
|
||||||
pub user_id: i32,
|
pub user_id: i32,
|
||||||
pub post_id: i32
|
pub post_id: i32,
|
||||||
|
pub ap_url: String
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Like {
|
impl Like {
|
||||||
|
@ -31,6 +33,14 @@ impl Like {
|
||||||
.expect("Unable to insert new like")
|
.expect("Unable to insert new like")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn update_ap_url(&self, conn: &PgConnection) {
|
||||||
|
if self.ap_url.len() == 0 {
|
||||||
|
diesel::update(self)
|
||||||
|
.set(likes::ap_url.eq(self.compute_id(conn)))
|
||||||
|
.get_result::<Like>(conn).expect("Couldn't update AP URL");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get(conn: &PgConnection, id: i32) -> Option<Like> {
|
pub fn get(conn: &PgConnection, id: i32) -> Option<Like> {
|
||||||
likes::table.filter(likes::id.eq(id))
|
likes::table.filter(likes::id.eq(id))
|
||||||
.limit(1)
|
.limit(1)
|
||||||
|
@ -39,6 +49,14 @@ impl Like {
|
||||||
.into_iter().nth(0)
|
.into_iter().nth(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn find_by_ap_url(conn: &PgConnection, ap_url: String) -> Option<Like> {
|
||||||
|
likes::table.filter(likes::ap_url.eq(ap_url))
|
||||||
|
.limit(1)
|
||||||
|
.load::<Like>(conn)
|
||||||
|
.expect("Error loading like by AP URL")
|
||||||
|
.into_iter().nth(0)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn for_user_on_post(conn: &PgConnection, user: &User, post: &Post) -> Option<Like> {
|
pub fn for_user_on_post(conn: &PgConnection, user: &User, post: &Post) -> Option<Like> {
|
||||||
likes::table.filter(likes::post_id.eq(post.id))
|
likes::table.filter(likes::post_id.eq(post.id))
|
||||||
.filter(likes::user_id.eq(user.id))
|
.filter(likes::user_id.eq(user.id))
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use rocket::response::Redirect;
|
use rocket::response::Redirect;
|
||||||
|
|
||||||
use activity_pub::activity::{Like, Delete};
|
use activity_pub::activity::{Like, Undo};
|
||||||
use activity_pub::outbox::broadcast;
|
use activity_pub::outbox::broadcast;
|
||||||
use db_conn::DbConn;
|
use db_conn::DbConn;
|
||||||
use models::likes;
|
use models::likes;
|
||||||
|
@ -12,17 +12,19 @@ fn create(blog: String, slug: String, user: User, conn: DbConn) -> Redirect {
|
||||||
let post = Post::find_by_slug(&*conn, slug.clone()).unwrap();
|
let post = Post::find_by_slug(&*conn, slug.clone()).unwrap();
|
||||||
|
|
||||||
if !user.has_liked(&*conn, &post) {
|
if !user.has_liked(&*conn, &post) {
|
||||||
likes::Like::insert(&*conn, likes::NewLike {
|
let like = likes::Like::insert(&*conn, likes::NewLike {
|
||||||
post_id: post.id,
|
post_id: post.id,
|
||||||
user_id: user.id
|
user_id: user.id,
|
||||||
|
ap_url: "".to_string()
|
||||||
});
|
});
|
||||||
|
like.update_ap_url(&*conn);
|
||||||
let act = Like::new(&user, &post, &*conn);
|
let act = Like::new(&user, &post, &*conn);
|
||||||
broadcast(&*conn, &user, act, user.get_followers(&*conn));
|
broadcast(&*conn, &user, act, user.get_followers(&*conn));
|
||||||
} else {
|
} else {
|
||||||
let like = likes::Like::for_user_on_post(&*conn, &user, &post).unwrap();
|
let like = likes::Like::for_user_on_post(&*conn, &user, &post).unwrap();
|
||||||
like.delete(&*conn);
|
like.delete(&*conn);
|
||||||
broadcast(&*conn, &user, Delete::new(&user, &like, &*conn), user.get_followers(&*conn));
|
broadcast(&*conn, &user, Undo::new(&user, &like, &*conn), user.get_followers(&*conn));
|
||||||
}
|
}
|
||||||
|
|
||||||
Redirect::to(format!("/~/{}/{}/", blog, slug).as_ref())
|
Redirect::to(format!("/~/{}/{}/", blog, slug).as_ref())
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,7 @@ table! {
|
||||||
user_id -> Int4,
|
user_id -> Int4,
|
||||||
post_id -> Int4,
|
post_id -> Int4,
|
||||||
creation_date -> Timestamp,
|
creation_date -> Timestamp,
|
||||||
|
ap_url -> Varchar,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue