2018-09-09 17:08:53 +02:00
use activitypub ::object ::Note ;
2018-06-04 21:57:03 +02:00
use rocket ::{
2018-06-24 18:58:57 +02:00
request ::LenientForm ,
2018-06-21 16:00:25 +02:00
response ::Redirect
2018-06-04 21:57:03 +02:00
} ;
2018-12-06 18:54:16 +01:00
use rocket_i18n ::I18n ;
2018-06-29 14:56:00 +02:00
use validator ::Validate ;
2018-12-06 18:54:16 +01:00
use template_utils ::Ructe ;
2018-05-10 11:44:57 +02:00
2018-12-23 11:13:36 +01:00
use plume_common ::{ utils , activity_pub ::{ broadcast , ApRequest ,
ActivityStream , inbox ::Deletable } } ;
2018-06-23 18:36:11 +02:00
use plume_models ::{
2018-06-19 21:16:18 +02:00
blogs ::Blog ,
2018-05-19 09:39:59 +02:00
comments ::* ,
2018-06-23 18:36:11 +02:00
db_conn ::DbConn ,
2018-12-23 11:12:15 +01:00
instance ::Instance ,
2018-09-09 17:08:53 +02:00
mentions ::Mention ,
2018-05-19 09:39:59 +02:00
posts ::Post ,
2018-09-09 17:08:53 +02:00
safe_string ::SafeString ,
2018-12-06 18:54:16 +01:00
tags ::Tag ,
2018-05-19 09:39:59 +02:00
users ::User
} ;
2018-12-02 17:37:51 +01:00
use Worker ;
2018-05-10 11:44:57 +02:00
2018-12-06 18:54:16 +01:00
#[ derive(Default, FromForm, Debug, Validate, Serialize) ]
pub struct NewCommentForm {
2018-06-27 00:19:18 +02:00
pub responding_to : Option < i32 > ,
2018-07-07 22:51:48 +02:00
#[ validate(length(min = " 1 " , message = " Your comment can't be empty " )) ]
2018-11-07 15:57:31 +01:00
pub content : String ,
pub warning : String ,
2018-05-10 11:44:57 +02:00
}
2018-12-06 18:54:16 +01:00
#[ post( " /~/<blog_name>/<slug>/comment " , data = " <form> " ) ]
pub fn create ( blog_name : String , slug : String , form : LenientForm < NewCommentForm > , user : User , conn : DbConn , worker : Worker , intl : I18n )
-> Result < Redirect , Option < Ructe > > {
2018-11-26 10:21:52 +01:00
let blog = Blog ::find_by_fqn ( & * conn , & blog_name ) . ok_or ( None ) ? ;
let post = Post ::find_by_slug ( & * conn , & slug , blog . id ) . ok_or ( None ) ? ;
2018-07-06 11:51:19 +02:00
form . validate ( )
. map ( | _ | {
2018-12-23 11:12:15 +01:00
let ( html , mentions , _hashtags ) = utils ::md_to_html ( form . content . as_ref ( ) , & Instance ::get_local ( & conn ) . expect ( " comments::create: Error getting local instance " ) . public_domain ) ;
2018-09-09 17:08:53 +02:00
let comm = Comment ::insert ( & * conn , NewComment {
content : SafeString ::new ( html . as_ref ( ) ) ,
2018-11-26 10:21:52 +01:00
in_response_to_id : form . responding_to ,
2018-09-09 17:08:53 +02:00
post_id : post . id ,
author_id : user . id ,
ap_url : None ,
2018-11-26 10:21:52 +01:00
sensitive : ! form . warning . is_empty ( ) ,
2018-12-24 11:23:04 +01:00
spoiler_text : form . warning . clone ( ) ,
public_visibility : true
2018-09-09 17:08:53 +02:00
} ) . update_ap_url ( & * conn ) ;
let new_comment = comm . create_activity ( & * conn ) ;
2018-05-19 00:04:30 +02:00
2018-09-09 17:08:53 +02:00
// save mentions
for ment in mentions {
2018-11-26 10:21:52 +01:00
Mention ::from_activity ( & * conn , & Mention ::build_activity ( & * conn , & ment ) , post . id , true , true ) ;
2018-09-09 17:08:53 +02:00
}
// federate
2018-09-09 13:19:11 +02:00
let dest = User ::one_by_instance ( & * conn ) ;
2018-07-26 17:51:41 +02:00
let user_clone = user . clone ( ) ;
2018-12-02 17:37:51 +01:00
worker . execute ( move | | broadcast ( & user_clone , new_comment , dest ) ) ;
2018-06-21 12:28:42 +02:00
2018-12-13 22:20:19 +01:00
Redirect ::to ( uri! ( super ::posts ::details : blog = blog_name , slug = slug , responding_to = _ ) )
2018-07-06 11:51:19 +02:00
} )
. map_err ( | errors | {
// TODO: de-duplicate this code
2018-12-24 11:23:04 +01:00
let comments = CommentTree ::from_post ( & * conn , & post , Some ( & user ) ) ;
2018-05-10 17:36:32 +02:00
2018-12-06 18:54:16 +01:00
let previous = form . responding_to . map ( | r | Comment ::get ( & * conn , r )
2018-12-23 11:12:15 +01:00
. expect ( " comments::create: Error retrieving previous comment " ) ) ;
2018-12-06 18:54:16 +01:00
Some ( render! ( posts ::details (
& ( & * conn , & intl . catalog , Some ( user . clone ( ) ) ) ,
post . clone ( ) ,
blog ,
& * form ,
errors ,
Tag ::for_post ( & * conn , post . id ) ,
2018-12-24 11:23:04 +01:00
comments ,
2018-12-06 18:54:16 +01:00
previous ,
2018-12-14 23:16:18 +01:00
post . count_likes ( & * conn ) ,
post . count_reshares ( & * conn ) ,
2018-12-06 18:54:16 +01:00
user . has_liked ( & * conn , & post ) ,
user . has_reshared ( & * conn , & post ) ,
user . is_following ( & * conn , post . get_authors ( & * conn ) [ 0 ] . id ) ,
post . get_authors ( & * conn ) [ 0 ] . clone ( )
) ) )
2018-09-09 12:53:22 +02:00
} )
2018-05-10 11:44:57 +02:00
}
2018-09-09 17:08:53 +02:00
2018-12-23 11:13:36 +01:00
#[ post( " /~/<blog>/<slug>/comment/<id>/delete " ) ]
pub fn delete ( blog : String , slug : String , id : i32 , user : User , conn : DbConn , worker : Worker ) -> Redirect {
if let Some ( comment ) = Comment ::get ( & * conn , id ) {
if comment . author_id = = user . id {
let dest = User ::one_by_instance ( & * conn ) ;
let delete_activity = comment . delete ( & * conn ) ;
worker . execute ( move | | broadcast ( & user , delete_activity , dest ) ) ;
}
}
Redirect ::to ( uri! ( super ::posts ::details : blog = blog , slug = slug , responding_to = _ ) )
}
2018-09-09 17:08:53 +02:00
#[ get( " /~/<_blog>/<_slug>/comment/<id> " ) ]
2018-12-06 18:54:16 +01:00
pub fn activity_pub ( _blog : String , _slug : String , id : i32 , _ap : ApRequest , conn : DbConn ) -> Option < ActivityStream < Note > > {
2018-11-26 10:21:52 +01:00
Comment ::get ( & * conn , id ) . map ( | c | ActivityStream ::new ( c . to_activity ( & * conn ) ) )
2018-09-09 17:08:53 +02:00
}