diff --git a/src/activity_pub/inbox.rs b/src/activity_pub/inbox.rs index 8b0856f2..03055675 100644 --- a/src/activity_pub/inbox.rs +++ b/src/activity_pub/inbox.rs @@ -40,8 +40,8 @@ pub trait FromActivity: Sized { } } -pub trait Notify { - fn notify(conn: &PgConnection, act: T, actor: Id); +pub trait Notify { + fn notify(&self, conn: &PgConnection); } pub trait Deletable { diff --git a/src/models/comments.rs b/src/models/comments.rs index 988ce3af..f943ddb5 100644 --- a/src/models/comments.rs +++ b/src/models/comments.rs @@ -137,27 +137,21 @@ impl FromActivity for Comment { author_id: User::from_url(conn, actor.clone().into()).unwrap().id, sensitive: false // "sensitive" is not a standard property, we need to think about how to support it with the activitypub crate }); - Comment::notify(conn, note, actor); + comm.notify(conn); comm } } -impl Notify for Comment { - fn notify(conn: &PgConnection, note: Note, _actor: Id) { - match Comment::find_by_ap_url(conn, note.object_props.id_string().unwrap()) { - Some(comment) => { - for author in comment.clone().get_post(conn).get_authors(conn) { - let comment = comment.clone(); - Notification::insert(conn, NewNotification { - title: "{{ data }} commented your article".to_string(), - data: Some(comment.get_author(conn).display_name.clone()), - content: Some(comment.get_post(conn).title), - link: comment.ap_url, - user_id: author.id - }); - } - }, - None => println!("Couldn't find comment by AP id, to create a new notification") - }; +impl Notify for Comment { + fn notify(&self, conn: &PgConnection) { + for author in self.get_post(conn).get_authors(conn) { + Notification::insert(conn, NewNotification { + title: "{{ data }} commented your article".to_string(), + data: Some(self.get_author(conn).display_name.clone()), + content: Some(self.get_post(conn).title), + link: self.ap_url.clone(), + user_id: author.id + }); + } } } diff --git a/src/models/follows.rs b/src/models/follows.rs index 06548625..35188165 100644 --- a/src/models/follows.rs +++ b/src/models/follows.rs @@ -62,15 +62,15 @@ impl FromActivity for Follow { } } -impl Notify for Follow { - fn notify(conn: &PgConnection, follow: FollowAct, actor: Id) { - let follower = User::from_url(conn, actor.into()).unwrap(); +impl Notify for Follow { + fn notify(&self, conn: &PgConnection) { + let follower = User::get(conn, self.follower_id).unwrap(); Notification::insert(conn, NewNotification { title: "{{ data }} started following you".to_string(), data: Some(follower.display_name.clone()), content: None, link: Some(follower.ap_url), - user_id: User::from_url(conn, follow.follow_props.object_link::().unwrap().into()).unwrap().id + user_id: self.following_id }); } } diff --git a/src/models/likes.rs b/src/models/likes.rs index 3efe9f76..38a4a193 100644 --- a/src/models/likes.rs +++ b/src/models/likes.rs @@ -77,7 +77,7 @@ impl Like { } impl FromActivity for Like { - fn from_activity(conn: &PgConnection, like: activity::Like, actor: Id) -> Like { + fn from_activity(conn: &PgConnection, like: activity::Like, _actor: Id) -> Like { let liker = User::from_url(conn, like.like_props.actor.as_str().unwrap().to_string()); let post = Post::find_by_ap_url(conn, like.like_props.object.as_str().unwrap().to_string()); let res = Like::insert(conn, NewLike { @@ -85,15 +85,15 @@ impl FromActivity for Like { user_id: liker.unwrap().id, ap_url: like.object_props.id_string().unwrap_or(String::from("")) }); - Like::notify(conn, like, actor); + res.notify(conn); res } } -impl Notify for Like { - fn notify(conn: &PgConnection, like: activity::Like, actor: Id) { - let liker = User::from_url(conn, actor.into()).unwrap(); - let post = Post::find_by_ap_url(conn, like.like_props.object_link::().unwrap().into()).unwrap(); +impl Notify for Like { + fn notify(&self, conn: &PgConnection) { + let liker = User::get(conn, self.user_id).unwrap(); + let post = Post::get(conn, self.post_id).unwrap(); for author in post.get_authors(conn) { let post = post.clone(); Notification::insert(conn, NewNotification { diff --git a/src/models/mentions.rs b/src/models/mentions.rs index aebdc7ae..fe4fe90a 100644 --- a/src/models/mentions.rs +++ b/src/models/mentions.rs @@ -49,6 +49,7 @@ impl Mention { pub fn build_activity(conn: &PgConnection, ment: String) -> link::Mention { let user = User::find_by_fqn(conn, ment.clone()); + println!("building act : {} -> {:?}", ment, user); let mut mention = link::Mention::default(); mention.link_props.set_href_string(user.clone().map(|u| u.ap_url).unwrap_or(String::new())).expect("Error setting mention's href"); mention.link_props.set_name_string(format!("@{}", ment)).expect("Error setting mention's name"); @@ -64,27 +65,28 @@ impl Mention { } pub fn from_activity(conn: &PgConnection, ment: link::Mention, inside: Id) -> Option { - let mentioned = User::find_by_ap_url(conn, ment.link_props.href_string().unwrap()).unwrap(); + let ap_url = ment.link_props.href_string().unwrap(); + let mentioned = User::find_by_ap_url(conn, ap_url).unwrap(); if let Some(post) = Post::find_by_ap_url(conn, inside.clone().into()) { - let res = Some(Mention::insert(conn, NewMention { + let res = Mention::insert(conn, NewMention { mentioned_id: mentioned.id, post_id: Some(post.id), comment_id: None, ap_url: ment.link_props.href_string().unwrap_or(String::new()) - })); - Mention::notify(conn, ment, Id::new(String::new())); - res + }); + res.notify(conn); + Some(res) } else { if let Some(comment) = Comment::find_by_ap_url(conn, inside.into()) { - let res =Some(Mention::insert(conn, NewMention { + let res = Mention::insert(conn, NewMention { mentioned_id: mentioned.id, post_id: None, comment_id: Some(comment.id), ap_url: ment.link_props.href_string().unwrap_or(String::new()) - })); - Mention::notify(conn, ment, Id::new(String::new())); - res + }); + res.notify(conn); + Some(res) } else { None } @@ -92,25 +94,20 @@ impl Mention { } } -impl Notify for Mention { - fn notify(conn: &PgConnection, ment: link::Mention, _actor: Id) { - match Mention::find_by_ap_url(conn, ment.link_props.href_string().unwrap()) { - Some(mention) => { - let author = mention.get_comment(conn) - .map(|c| c.get_author(conn).display_name.clone()) - .unwrap_or(mention.get_post(conn).unwrap().get_authors(conn)[0].display_name.clone()); +impl Notify for Mention { + fn notify(&self, conn: &PgConnection) { + let author = self.get_comment(conn) + .map(|c| c.get_author(conn).display_name.clone()) + .unwrap_or(self.get_post(conn).unwrap().get_authors(conn)[0].display_name.clone()); - mention.get_mentioned(conn).map(|m| { - Notification::insert(conn, NewNotification { - title: "{{ data }} mentioned you.".to_string(), - data: Some(author), - content: None, - link: Some(mention.get_post(conn).map(|p| p.ap_url).unwrap_or(mention.get_comment(conn).unwrap().ap_url.unwrap_or(String::new()))), - user_id: m.id - }); - }); - }, - None => println!("Couldn't find mention by AP URL, to create a new notification") - }; + self.get_mentioned(conn).map(|m| { + Notification::insert(conn, NewNotification { + title: "{{ data }} mentioned you.".to_string(), + data: Some(author), + content: None, + link: Some(self.get_post(conn).map(|p| p.ap_url).unwrap_or_else(|| self.get_comment(conn).unwrap().ap_url.unwrap_or(String::new()))), + user_id: m.id + }); + }); } } diff --git a/src/models/reshares.rs b/src/models/reshares.rs index f1858cea..40a210d3 100644 --- a/src/models/reshares.rs +++ b/src/models/reshares.rs @@ -73,7 +73,7 @@ impl Reshare { } impl FromActivity for Reshare { - fn from_activity(conn: &PgConnection, announce: Announce, actor: Id) -> Reshare { + fn from_activity(conn: &PgConnection, announce: Announce, _actor: Id) -> Reshare { let user = User::from_url(conn, announce.announce_props.actor.as_str().unwrap().to_string()); let post = Post::find_by_ap_url(conn, announce.announce_props.object.as_str().unwrap().to_string()); let reshare = Reshare::insert(conn, NewReshare { @@ -81,15 +81,15 @@ impl FromActivity for Reshare { user_id: user.unwrap().id, ap_url: announce.object_props.id_string().unwrap_or(String::from("")) }); - Reshare::notify(conn, announce, actor); + reshare.notify(conn); reshare } } -impl Notify for Reshare { - fn notify(conn: &PgConnection, announce: Announce, actor: Id) { - let actor = User::from_url(conn, actor.into()).unwrap(); - let post = Post::find_by_ap_url(conn, announce.announce_props.object_link::().unwrap().into()).unwrap(); +impl Notify for Reshare { + fn notify(&self, conn: &PgConnection) { + let actor = User::get(conn, self.user_id).unwrap(); + let post = self.get_post(conn).unwrap(); for author in post.get_authors(conn) { let post = post.clone(); Notification::insert(conn, NewNotification { diff --git a/src/models/users.rs b/src/models/users.rs index 5a075487..ee7639c8 100644 --- a/src/models/users.rs +++ b/src/models/users.rs @@ -47,7 +47,7 @@ use safe_string::SafeString; pub const AUTH_COOKIE: &'static str = "user_id"; -#[derive(Queryable, Identifiable, Serialize, Deserialize, Clone)] +#[derive(Queryable, Identifiable, Serialize, Deserialize, Clone, Debug)] pub struct User { pub id: i32, pub username: String, diff --git a/src/routes/comments.rs b/src/routes/comments.rs index 49e678be..e7fe466a 100644 --- a/src/routes/comments.rs +++ b/src/routes/comments.rs @@ -4,7 +4,7 @@ use rocket::{ }; use rocket_contrib::Template; -use activity_pub::{broadcast, IntoId, inbox::Notify}; +use activity_pub::{broadcast, inbox::Notify}; use db_conn::DbConn; use models::{ blogs::Blog, @@ -53,12 +53,12 @@ fn create(blog_name: String, slug: String, query: CommentQuery, data: Form Redirect { ap_url: "".to_string() }); like.update_ap_url(&*conn); + like.notify(&*conn); - likes::Like::notify(&*conn, like.into_activity(&*conn), user.clone().into_id()); broadcast(&*conn, &user, like.into_activity(&*conn), user.get_followers(&*conn)); } else { let like = likes::Like::find_by_user_on_post(&*conn, user.id, post.id).unwrap(); diff --git a/src/routes/reshares.rs b/src/routes/reshares.rs index 6da07f77..5212faae 100644 --- a/src/routes/reshares.rs +++ b/src/routes/reshares.rs @@ -1,6 +1,6 @@ use rocket::response::{Redirect, Flash}; -use activity_pub::{broadcast, IntoId, inbox::Notify}; +use activity_pub::{broadcast, inbox::Notify}; use db_conn::DbConn; use models::{ blogs::Blog, @@ -23,8 +23,8 @@ fn create(blog: String, slug: String, user: User, conn: DbConn) -> Redirect { ap_url: "".to_string() }); reshare.update_ap_url(&*conn); + reshare.notify(&*conn); - Reshare::notify(&*conn, reshare.into_activity(&*conn), user.clone().into_id()); broadcast(&*conn, &user, reshare.into_activity(&*conn), user.get_followers(&*conn)); } else { let reshare = Reshare::find_by_user_on_post(&*conn, user.id, post.id).unwrap(); diff --git a/src/routes/user.rs b/src/routes/user.rs index 7a778469..da78cf6a 100644 --- a/src/routes/user.rs +++ b/src/routes/user.rs @@ -71,16 +71,17 @@ fn dashboard_auth() -> Flash { #[get("/@//follow")] fn follow(name: String, conn: DbConn, user: User) -> Redirect { let target = User::find_by_fqn(&*conn, name.clone()).unwrap(); - follows::Follow::insert(&*conn, follows::NewFollow { + let f = follows::Follow::insert(&*conn, follows::NewFollow { follower_id: user.id, following_id: target.id }); + f.notify(&*conn); + let mut act = Follow::default(); act.follow_props.set_actor_link::(user.clone().into_id()).unwrap(); act.follow_props.set_object_object(user.into_activity(&*conn)).unwrap(); act.object_props.set_id_string(format!("{}/follow/{}", user.ap_url, target.ap_url)).unwrap(); - follows::Follow::notify(&*conn, act.clone(), user.clone().into_id()); broadcast(&*conn, &user, act, vec![target]); Redirect::to(uri!(details: name = name)) } diff --git a/src/utils.rs b/src/utils.rs index f65ff1c9..8b14959c 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -60,7 +60,7 @@ pub fn md_to_html(md: &str) -> (String, Vec) { _ => (vec![evt], vec![]) }).unzip(); let parser = parser.into_iter().flatten(); - let mentions = mentions.into_iter().flatten(); + let mentions = mentions.into_iter().flatten().map(|m| String::from(m.trim())); // TODO: fetch mentionned profiles in background, if needed