2018-07-08 20:01:19 +02:00
use activitypub ::{ Actor , activity ::{ Accept , Follow as FollowAct } , actor ::Person } ;
2018-05-01 15:06:31 +02:00
use diesel ::{ self , PgConnection , ExpressionMethods , QueryDsl , RunQueryDsl } ;
2018-06-23 18:36:11 +02:00
use plume_common ::activity_pub ::{ broadcast , Id , IntoId , inbox ::{ FromActivity , Notify , WithInbox } , sign ::Signer } ;
use blogs ::Blog ;
use notifications ::* ;
use users ::User ;
2018-05-01 15:06:31 +02:00
use schema ::follows ;
2018-05-01 15:23:23 +02:00
#[ derive(Queryable, Identifiable, Associations) ]
#[ belongs_to(User, foreign_key = " following_id " ) ]
2018-05-01 15:06:31 +02:00
pub struct Follow {
pub id : i32 ,
pub follower_id : i32 ,
pub following_id : i32
}
#[ derive(Insertable) ]
#[ table_name = " follows " ]
pub struct NewFollow {
pub follower_id : i32 ,
pub following_id : i32
}
impl Follow {
2018-06-18 15:57:38 +02:00
insert! ( follows , NewFollow ) ;
2018-06-18 15:44:23 +02:00
get! ( follows ) ;
2018-06-12 21:10:08 +02:00
2018-06-22 17:17:53 +02:00
/// from -> The one sending the follow request
/// target -> The target of the request, responding with Accept
2018-06-23 13:50:14 +02:00
pub fn accept_follow < A : Signer + IntoId + Clone , B : Clone + WithInbox + Actor + IntoId > (
2018-06-12 21:10:08 +02:00
conn : & PgConnection ,
2018-06-22 17:17:53 +02:00
from : & B ,
target : & A ,
2018-06-12 21:10:08 +02:00
follow : FollowAct ,
from_id : i32 ,
target_id : i32
) -> Follow {
let res = Follow ::insert ( conn , NewFollow {
follower_id : from_id ,
following_id : target_id
} ) ;
let mut accept = Accept ::default ( ) ;
2018-06-23 13:50:14 +02:00
let accept_id = format! ( " {} #accept " , follow . object_props . id_string ( ) . unwrap_or ( String ::new ( ) ) ) ;
accept . object_props . set_id_string ( accept_id ) . expect ( " accept_follow: id error " ) ;
accept . object_props . set_to_link ( from . clone ( ) . into_id ( ) ) . expect ( " accept_follow: to error " ) ;
accept . object_props . set_cc_link_vec ::< Id > ( vec! [ ] ) . expect ( " accept_follow: cc error " ) ;
2018-06-22 17:17:53 +02:00
accept . accept_props . set_actor_link ::< Id > ( target . clone ( ) . into_id ( ) ) . unwrap ( ) ;
2018-06-12 21:10:08 +02:00
accept . accept_props . set_object_object ( follow ) . unwrap ( ) ;
2018-06-22 17:17:53 +02:00
broadcast ( & * target , accept , vec! [ from . clone ( ) ] ) ;
2018-06-12 21:10:08 +02:00
res
}
}
2018-06-23 18:36:11 +02:00
impl FromActivity < FollowAct , PgConnection > for Follow {
2018-06-12 21:10:08 +02:00
fn from_activity ( conn : & PgConnection , follow : FollowAct , _actor : Id ) -> Follow {
2018-07-08 20:01:19 +02:00
let from_id = follow . follow_props . actor_link ::< Id > ( ) . map ( | l | l . into ( ) )
. unwrap_or_else ( | _ | follow . follow_props . actor_object ::< Person > ( ) . expect ( " No actor object (nor ID) on Follow " ) . object_props . id_string ( ) . expect ( " No ID on actor on Follow " ) ) ;
let from = User ::from_url ( conn , from_id ) . unwrap ( ) ;
2018-06-12 21:10:08 +02:00
match User ::from_url ( conn , follow . follow_props . object . as_str ( ) . unwrap ( ) . to_string ( ) ) {
2018-06-22 17:17:53 +02:00
Some ( user ) = > Follow ::accept_follow ( conn , & from , & user , follow , from . id , user . id ) ,
2018-06-12 21:10:08 +02:00
None = > {
let blog = Blog ::from_url ( conn , follow . follow_props . object . as_str ( ) . unwrap ( ) . to_string ( ) ) . unwrap ( ) ;
Follow ::accept_follow ( conn , & from , & blog , follow , from . id , blog . id )
}
}
}
2018-05-01 15:06:31 +02:00
}
2018-06-17 21:37:10 +02:00
2018-06-23 18:36:11 +02:00
impl Notify < PgConnection > for Follow {
2018-06-20 23:51:47 +02:00
fn notify ( & self , conn : & PgConnection ) {
2018-06-17 21:37:10 +02:00
Notification ::insert ( conn , NewNotification {
2018-07-26 15:46:10 +02:00
kind : notification_kind ::FOLLOW . to_string ( ) ,
object_id : self . id ,
2018-06-20 23:51:47 +02:00
user_id : self . following_id
2018-06-17 21:37:10 +02:00
} ) ;
}
}