Allow likes to be deleted with AP
This commit is contained in:
		
							parent
							
								
									bae49bcb47
								
							
						
					
					
						commit
						601fe7cf4f
					
				
							
								
								
									
										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 { | ||||
|         "Follow".to_string() | ||||
|         "Like".to_string() | ||||
|     } | ||||
| 
 | ||||
|     fn serialize(&self) -> serde_json::Value { | ||||
|         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, | ||||
|             "actor": self.actor, | ||||
|             "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()); | ||||
|                 Like::insert(conn, NewLike { | ||||
|                     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) | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -13,14 +13,16 @@ pub struct Like { | ||||
|     pub id: i32, | ||||
|     pub user_id: i32, | ||||
|     pub post_id: i32, | ||||
|     pub creation_date: chrono::NaiveDateTime | ||||
|     pub creation_date: chrono::NaiveDateTime, | ||||
|     pub ap_url: String | ||||
| } | ||||
| 
 | ||||
| #[derive(Insertable)] | ||||
| #[table_name = "likes"] | ||||
| pub struct NewLike { | ||||
|     pub user_id: i32, | ||||
|     pub post_id: i32 | ||||
|     pub post_id: i32, | ||||
|     pub ap_url: String | ||||
| } | ||||
| 
 | ||||
| impl Like { | ||||
| @ -31,6 +33,14 @@ impl 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> { | ||||
|         likes::table.filter(likes::id.eq(id)) | ||||
|             .limit(1) | ||||
| @ -39,6 +49,14 @@ impl Like { | ||||
|             .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> { | ||||
|         likes::table.filter(likes::post_id.eq(post.id)) | ||||
|             .filter(likes::user_id.eq(user.id)) | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| use rocket::response::Redirect; | ||||
| 
 | ||||
| use activity_pub::activity::{Like, Delete}; | ||||
| use activity_pub::activity::{Like, Undo}; | ||||
| use activity_pub::outbox::broadcast; | ||||
| use db_conn::DbConn; | ||||
| 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(); | ||||
| 
 | ||||
|     if !user.has_liked(&*conn, &post) { | ||||
|         likes::Like::insert(&*conn, likes::NewLike { | ||||
|         let like = likes::Like::insert(&*conn, likes::NewLike { | ||||
|                 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); | ||||
|         broadcast(&*conn, &user, act, user.get_followers(&*conn)); | ||||
|     } else { | ||||
|         let like = likes::Like::for_user_on_post(&*conn, &user, &post).unwrap(); | ||||
|         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()) | ||||
| } | ||||
|  | ||||
| @ -62,6 +62,7 @@ table! { | ||||
|         user_id -> Int4, | ||||
|         post_id -> Int4, | ||||
|         creation_date -> Timestamp, | ||||
|         ap_url -> Varchar, | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user