2018-06-10 13:13:07 +02:00
use activitypub ::activity ;
2018-09-26 17:22:42 +02:00
use chrono ::NaiveDateTime ;
use diesel ::{ self , QueryDsl , RunQueryDsl , ExpressionMethods } ;
2018-05-10 17:54:35 +02:00
2018-06-23 18:36:11 +02:00
use plume_common ::activity_pub ::{
2018-06-23 14:17:17 +02:00
PUBLIC_VISIBILTY ,
2018-06-12 21:10:08 +02:00
Id ,
2018-05-19 09:39:59 +02:00
IntoId ,
2018-06-20 11:01:25 +02:00
inbox ::{ FromActivity , Deletable , Notify }
2018-05-19 09:39:59 +02:00
} ;
2018-09-26 17:22:42 +02:00
use Connection ;
2018-06-23 18:36:11 +02:00
use notifications ::* ;
use posts ::Post ;
use users ::User ;
2018-05-10 17:54:35 +02:00
use schema ::likes ;
2018-09-27 23:06:40 +02:00
#[ derive(Clone, Queryable, Identifiable) ]
2018-05-10 17:54:35 +02:00
pub struct Like {
2018-05-10 18:07:23 +02:00
pub id : i32 ,
pub user_id : i32 ,
pub post_id : i32 ,
2018-09-26 17:22:42 +02:00
pub creation_date : NaiveDateTime ,
2018-05-13 12:44:05 +02:00
pub ap_url : String
2018-05-10 17:54:35 +02:00
}
2018-06-22 22:45:37 +02:00
#[ derive(Default, Insertable) ]
2018-05-10 17:54:35 +02:00
#[ table_name = " likes " ]
pub struct NewLike {
2018-05-10 18:07:23 +02:00
pub user_id : i32 ,
2018-05-13 12:44:05 +02:00
pub post_id : i32 ,
pub ap_url : String
2018-05-10 17:54:35 +02:00
}
impl Like {
2018-06-18 15:57:38 +02:00
insert! ( likes , NewLike ) ;
get! ( likes ) ;
find_by! ( likes , find_by_ap_url , ap_url as String ) ;
2018-06-18 17:13:09 +02:00
find_by! ( likes , find_by_user_on_post , user_id as i32 , post_id as i32 ) ;
2018-05-10 18:07:23 +02:00
2018-09-26 17:22:42 +02:00
pub fn update_ap_url ( & self , conn : & Connection ) {
2018-05-13 12:44:05 +02:00
if self . ap_url . len ( ) = = 0 {
diesel ::update ( self )
2018-06-23 14:40:10 +02:00
. set ( likes ::ap_url . eq ( format! (
" {}/like/{} " ,
2018-10-20 08:44:33 +02:00
User ::get ( conn , self . user_id ) . expect ( " Like::update_ap_url: user error " ) . ap_url ,
Post ::get ( conn , self . post_id ) . expect ( " Like::update_ap_url: post error " ) . ap_url
2018-06-23 14:40:10 +02:00
) ) )
2018-10-20 08:44:33 +02:00
. execute ( conn ) . expect ( " Like::update_ap_url: update error " ) ;
2018-05-13 12:44:05 +02:00
}
}
2018-09-26 17:22:42 +02:00
pub fn into_activity ( & self , conn : & Connection ) -> activity ::Like {
2018-05-19 00:04:30 +02:00
let mut act = activity ::Like ::default ( ) ;
2018-10-20 08:44:33 +02:00
act . like_props . set_actor_link ( User ::get ( conn , self . user_id ) . expect ( " Like::into_activity: user error " ) . into_id ( ) ) . expect ( " Like::into_activity: actor error " ) ;
act . like_props . set_object_link ( Post ::get ( conn , self . post_id ) . expect ( " Like::into_activity: post error " ) . into_id ( ) ) . expect ( " Like::into_activity: object error " ) ;
2018-06-23 14:17:17 +02:00
act . object_props . set_to_link ( Id ::new ( PUBLIC_VISIBILTY . to_string ( ) ) ) . expect ( " Like::into_activity: to error " ) ;
act . object_props . set_cc_link_vec ::< Id > ( vec! [ ] ) . expect ( " Like::into_activity: cc error " ) ;
2018-06-23 14:40:10 +02:00
act . object_props . set_id_string ( self . ap_url . clone ( ) ) . expect ( " Like::into_activity: id error " ) ;
2018-05-19 00:04:30 +02:00
act
2018-05-12 22:56:57 +02:00
}
2018-05-10 17:54:35 +02:00
}
2018-05-12 23:34:13 +02:00
2018-09-26 17:22:42 +02:00
impl FromActivity < activity ::Like , Connection > for Like {
fn from_activity ( conn : & Connection , like : activity ::Like , _actor : Id ) -> Like {
2018-10-20 08:44:33 +02:00
let liker = User ::from_url ( conn , like . like_props . actor . as_str ( ) . expect ( " Like::from_activity: actor error " ) . to_string ( ) ) ;
let post = Post ::find_by_ap_url ( conn , like . like_props . object . as_str ( ) . expect ( " Like::from_activity: object error " ) . to_string ( ) ) ;
2018-06-17 21:37:10 +02:00
let res = Like ::insert ( conn , NewLike {
2018-10-20 08:44:33 +02:00
post_id : post . expect ( " Like::from_activity: post error " ) . id ,
user_id : liker . expect ( " Like::from_activity: user error " ) . id ,
2018-06-12 21:10:08 +02:00
ap_url : like . object_props . id_string ( ) . unwrap_or ( String ::from ( " " ) )
2018-06-17 21:37:10 +02:00
} ) ;
2018-06-20 23:51:47 +02:00
res . notify ( conn ) ;
2018-06-17 21:37:10 +02:00
res
}
}
2018-09-26 17:22:42 +02:00
impl Notify < Connection > for Like {
fn notify ( & self , conn : & Connection ) {
2018-10-20 08:44:33 +02:00
let post = Post ::get ( conn , self . post_id ) . expect ( " Like::notify: post error " ) ;
2018-06-17 21:37:10 +02:00
for author in post . get_authors ( conn ) {
Notification ::insert ( conn , NewNotification {
2018-07-26 15:46:10 +02:00
kind : notification_kind ::LIKE . to_string ( ) ,
object_id : self . id ,
2018-06-17 21:37:10 +02:00
user_id : author . id
} ) ;
}
2018-06-12 21:10:08 +02:00
}
}
2018-09-26 17:22:42 +02:00
impl Deletable < Connection , activity ::Undo > for Like {
fn delete ( & self , conn : & Connection ) -> activity ::Undo {
2018-10-20 08:44:33 +02:00
diesel ::delete ( self ) . execute ( conn ) . expect ( " Like::delete: delete error " ) ;
2018-09-01 17:28:47 +02:00
2018-09-08 00:29:50 +02:00
// delete associated notification if any
if let Some ( notif ) = Notification ::find ( conn , notification_kind ::LIKE , self . id ) {
2018-10-20 08:44:33 +02:00
diesel ::delete ( & notif ) . execute ( conn ) . expect ( " Like::delete: notification error " ) ;
2018-09-08 00:29:50 +02:00
}
2018-09-01 17:28:47 +02:00
let mut act = activity ::Undo ::default ( ) ;
2018-10-20 08:44:33 +02:00
act . undo_props . set_actor_link ( User ::get ( conn , self . user_id ) . expect ( " Like::delete: user error " ) . into_id ( ) ) . expect ( " Like::delete: actor error " ) ;
2018-09-01 17:28:47 +02:00
act . undo_props . set_object_object ( self . into_activity ( conn ) ) . expect ( " Like::delete: object error " ) ;
act . object_props . set_id_string ( format! ( " {} #delete " , self . ap_url ) ) . expect ( " Like::delete: id error " ) ;
act . object_props . set_to_link ( Id ::new ( PUBLIC_VISIBILTY . to_string ( ) ) ) . expect ( " Like::delete: to error " ) ;
act . object_props . set_cc_link_vec ::< Id > ( vec! [ ] ) . expect ( " Like::delete: cc error " ) ;
act
}
2018-09-08 00:29:50 +02:00
2018-10-22 17:29:25 +02:00
fn delete_id ( id : String , actor_id : String , conn : & Connection ) {
2018-06-12 21:10:08 +02:00
if let Some ( like ) = Like ::find_by_ap_url ( conn , id . into ( ) ) {
2018-10-22 17:29:25 +02:00
if let Some ( user ) = User ::find_by_ap_url ( conn , actor_id ) {
if user . id = = like . user_id {
like . delete ( conn ) ;
}
}
2018-06-12 21:10:08 +02:00
}
}
}