finish this

This commit is contained in:
Felix Ableitner 2020-12-01 17:10:58 +01:00
parent 9cbb80ca8e
commit dbf9c69709
19 changed files with 210 additions and 195 deletions

View file

@ -1,6 +1,7 @@
use crate::{ use crate::{
activities::receive::get_actor_as_user, activities::receive::get_actor_as_user,
fetcher::get_or_fetch_and_insert_comment, fetcher::get_or_fetch_and_insert_comment,
objects::FromApub,
ActorType, ActorType,
NoteExt, NoteExt,
}; };
@ -10,16 +11,15 @@ use activitystreams::{
}; };
use anyhow::{anyhow, Context}; use anyhow::{anyhow, Context};
use lemmy_db::{ use lemmy_db::{
comment::{Comment, CommentForm, CommentLike, CommentLikeForm}, comment::{Comment, CommentLike, CommentLikeForm},
comment_view::CommentView, comment_view::CommentView,
post::Post, post::Post,
Crud,
Likeable, Likeable,
}; };
use lemmy_structs::{blocking, comment::CommentResponse, send_local_notifs}; use lemmy_structs::{blocking, comment::CommentResponse, send_local_notifs};
use lemmy_utils::{location_info, utils::scrape_text_for_mentions, LemmyError}; use lemmy_utils::{location_info, utils::scrape_text_for_mentions, LemmyError};
use lemmy_websocket::{messages::SendComment, LemmyContext, UserOperation}; use lemmy_websocket::{messages::SendComment, LemmyContext, UserOperation};
use crate::objects::FromApub; use url::Url;
pub(crate) async fn receive_create_comment( pub(crate) async fn receive_create_comment(
create: Create, create: Create,
@ -30,8 +30,8 @@ pub(crate) async fn receive_create_comment(
let note = NoteExt::from_any_base(create.object().to_owned().one().context(location_info!())?)? let note = NoteExt::from_any_base(create.object().to_owned().one().context(location_info!())?)?
.context(location_info!())?; .context(location_info!())?;
let comment = // TODO: need to do the check for locked post before calling this
CommentForm::from_apub(&note, context, Some(user.actor_id()?), request_counter).await?; let comment = Comment::from_apub(&note, context, Some(user.actor_id()?), request_counter).await?;
let post_id = comment.post_id; let post_id = comment.post_id;
let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??; let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
@ -39,27 +39,17 @@ pub(crate) async fn receive_create_comment(
return Err(anyhow!("Post is locked").into()); return Err(anyhow!("Post is locked").into());
} }
let inserted_comment =
blocking(context.pool(), move |conn| Comment::upsert(conn, &comment)).await??;
// Note: // Note:
// Although mentions could be gotten from the post tags (they are included there), or the ccs, // Although mentions could be gotten from the post tags (they are included there), or the ccs,
// Its much easier to scrape them from the comment body, since the API has to do that // Its much easier to scrape them from the comment body, since the API has to do that
// anyway. // anyway.
let mentions = scrape_text_for_mentions(&inserted_comment.content); let mentions = scrape_text_for_mentions(&comment.content);
let recipient_ids = send_local_notifs( let recipient_ids =
mentions, send_local_notifs(mentions, comment.clone(), &user, post, context.pool(), true).await?;
inserted_comment.clone(),
&user,
post,
context.pool(),
true,
)
.await?;
// Refetch the view // Refetch the view
let comment_view = blocking(context.pool(), move |conn| { let comment_view = blocking(context.pool(), move |conn| {
CommentView::read(conn, inserted_comment.id, None) CommentView::read(conn, comment.id, None)
}) })
.await??; .await??;
@ -87,32 +77,20 @@ pub(crate) async fn receive_update_comment(
.context(location_info!())?; .context(location_info!())?;
let user = get_actor_as_user(&update, context, request_counter).await?; let user = get_actor_as_user(&update, context, request_counter).await?;
let comment = let comment = Comment::from_apub(&note, context, Some(user.actor_id()?), request_counter).await?;
CommentForm::from_apub(&note, context, Some(user.actor_id()?), request_counter).await?;
// TODO: why fetch?
let original_comment_id = let original_comment_id =
get_or_fetch_and_insert_comment(&comment.get_ap_id()?, context, request_counter) get_or_fetch_and_insert_comment(&Url::parse(&comment.ap_id)?, context, request_counter)
.await? .await?
.id; .id;
let updated_comment = blocking(context.pool(), move |conn| { let post_id = comment.post_id;
Comment::update(conn, original_comment_id, &comment)
})
.await??;
let post_id = updated_comment.post_id;
let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??; let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
let mentions = scrape_text_for_mentions(&updated_comment.content); let mentions = scrape_text_for_mentions(&comment.content);
let recipient_ids = send_local_notifs( let recipient_ids =
mentions, send_local_notifs(mentions, comment, &user, post, context.pool(), false).await?;
updated_comment,
&user,
post,
context.pool(),
false,
)
.await?;
// Refetch the view // Refetch the view
let comment_view = blocking(context.pool(), move |conn| { let comment_view = blocking(context.pool(), move |conn| {
@ -144,11 +122,13 @@ pub(crate) async fn receive_like_comment(
.context(location_info!())?; .context(location_info!())?;
let user = get_actor_as_user(&like, context, request_counter).await?; let user = get_actor_as_user(&like, context, request_counter).await?;
let comment = CommentForm::from_apub(&note, context, None, request_counter).await?; let comment = Comment::from_apub(&note, context, None, request_counter).await?;
let comment_id = get_or_fetch_and_insert_comment(&comment.get_ap_id()?, context, request_counter) // TODO: why do we need to fetch here if we already have the comment?
.await? let comment_id =
.id; get_or_fetch_and_insert_comment(&Url::parse(&comment.ap_id)?, context, request_counter)
.await?
.id;
let like_form = CommentLikeForm { let like_form = CommentLikeForm {
comment_id, comment_id,
@ -201,11 +181,13 @@ pub(crate) async fn receive_dislike_comment(
.context(location_info!())?; .context(location_info!())?;
let user = get_actor_as_user(&dislike, context, request_counter).await?; let user = get_actor_as_user(&dislike, context, request_counter).await?;
let comment = CommentForm::from_apub(&note, context, None, request_counter).await?; let comment = Comment::from_apub(&note, context, None, request_counter).await?;
let comment_id = get_or_fetch_and_insert_comment(&comment.get_ap_id()?, context, request_counter) // TODO: same as above, why fetch here?
.await? let comment_id =
.id; get_or_fetch_and_insert_comment(&Url::parse(&comment.ap_id)?, context, request_counter)
.await?
.id;
let like_form = CommentLikeForm { let like_form = CommentLikeForm {
comment_id, comment_id,

View file

@ -1,19 +1,20 @@
use crate::{ use crate::{
activities::receive::get_actor_as_user, activities::receive::get_actor_as_user,
fetcher::get_or_fetch_and_insert_comment, fetcher::get_or_fetch_and_insert_comment,
objects::FromApub,
NoteExt, NoteExt,
}; };
use crate::objects::FromApub;
use activitystreams::{activity::*, prelude::*}; use activitystreams::{activity::*, prelude::*};
use anyhow::Context; use anyhow::Context;
use lemmy_db::{ use lemmy_db::{
comment::{Comment, CommentForm, CommentLike}, comment::{Comment, CommentLike},
comment_view::CommentView, comment_view::CommentView,
Likeable, Likeable,
}; };
use lemmy_structs::{blocking, comment::CommentResponse}; use lemmy_structs::{blocking, comment::CommentResponse};
use lemmy_utils::{location_info, LemmyError}; use lemmy_utils::{location_info, LemmyError};
use lemmy_websocket::{messages::SendComment, LemmyContext, UserOperation}; use lemmy_websocket::{messages::SendComment, LemmyContext, UserOperation};
use url::Url;
pub(crate) async fn receive_undo_like_comment( pub(crate) async fn receive_undo_like_comment(
like: &Like, like: &Like,
@ -24,11 +25,13 @@ pub(crate) async fn receive_undo_like_comment(
let note = NoteExt::from_any_base(like.object().to_owned().one().context(location_info!())?)? let note = NoteExt::from_any_base(like.object().to_owned().one().context(location_info!())?)?
.context(location_info!())?; .context(location_info!())?;
let comment = CommentForm::from_apub(&note, context, None, request_counter).await?; let comment = Comment::from_apub(&note, context, None, request_counter).await?;
let comment_id = get_or_fetch_and_insert_comment(&comment.get_ap_id()?, context, request_counter) // TODO: why?
.await? let comment_id =
.id; get_or_fetch_and_insert_comment(&Url::parse(&comment.ap_id)?, context, request_counter)
.await?
.id;
let user_id = user.id; let user_id = user.id;
blocking(context.pool(), move |conn| { blocking(context.pool(), move |conn| {
@ -74,11 +77,13 @@ pub(crate) async fn receive_undo_dislike_comment(
)? )?
.context(location_info!())?; .context(location_info!())?;
let comment = CommentForm::from_apub(&note, context, None, request_counter).await?; let comment = Comment::from_apub(&note, context, None, request_counter).await?;
let comment_id = get_or_fetch_and_insert_comment(&comment.get_ap_id()?, context, request_counter) // TODO
.await? let comment_id =
.id; get_or_fetch_and_insert_comment(&Url::parse(&comment.ap_id)?, context, request_counter)
.await?
.id;
let user_id = user.id; let user_id = user.id;
blocking(context.pool(), move |conn| { blocking(context.pool(), move |conn| {

View file

@ -1,24 +1,24 @@
use crate::{ use crate::{
activities::receive::get_actor_as_user, activities::receive::get_actor_as_user,
fetcher::get_or_fetch_and_insert_post, fetcher::get_or_fetch_and_insert_post,
objects::FromApub,
ActorType, ActorType,
PageExt, PageExt,
}; };
use crate::objects::FromApub;
use activitystreams::{ use activitystreams::{
activity::{Create, Dislike, Like, Remove, Update}, activity::{Create, Dislike, Like, Remove, Update},
prelude::*, prelude::*,
}; };
use anyhow::Context; use anyhow::Context;
use lemmy_db::{ use lemmy_db::{
post::{Post, PostForm, PostLike, PostLikeForm}, post::{Post, PostLike, PostLikeForm},
post_view::PostView, post_view::PostView,
Crud,
Likeable, Likeable,
}; };
use lemmy_structs::{blocking, post::PostResponse}; use lemmy_structs::{blocking, post::PostResponse};
use lemmy_utils::{location_info, LemmyError}; use lemmy_utils::{location_info, LemmyError};
use lemmy_websocket::{messages::SendPost, LemmyContext, UserOperation}; use lemmy_websocket::{messages::SendPost, LemmyContext, UserOperation};
use url::Url;
pub(crate) async fn receive_create_post( pub(crate) async fn receive_create_post(
create: Create, create: Create,
@ -29,16 +29,12 @@ pub(crate) async fn receive_create_post(
let page = PageExt::from_any_base(create.object().to_owned().one().context(location_info!())?)? let page = PageExt::from_any_base(create.object().to_owned().one().context(location_info!())?)?
.context(location_info!())?; .context(location_info!())?;
let post = PostForm::from_apub(&page, context, Some(user.actor_id()?), request_counter).await?; let post = Post::from_apub(&page, context, Some(user.actor_id()?), request_counter).await?;
// Using an upsert, since likes (which fetch the post), sometimes come in before the create
// resulting in double posts.
let inserted_post = blocking(context.pool(), move |conn| Post::upsert(conn, &post)).await??;
// Refetch the view // Refetch the view
let inserted_post_id = inserted_post.id; let post_id = post.id;
let post_view = blocking(context.pool(), move |conn| { let post_view = blocking(context.pool(), move |conn| {
PostView::read(conn, inserted_post_id, None) PostView::read(conn, post_id, None)
}) })
.await??; .await??;
@ -62,16 +58,13 @@ pub(crate) async fn receive_update_post(
let page = PageExt::from_any_base(update.object().to_owned().one().context(location_info!())?)? let page = PageExt::from_any_base(update.object().to_owned().one().context(location_info!())?)?
.context(location_info!())?; .context(location_info!())?;
let post = PostForm::from_apub(&page, context, Some(user.actor_id()?), request_counter).await?; let post = Post::from_apub(&page, context, Some(user.actor_id()?), request_counter).await?;
let original_post_id = get_or_fetch_and_insert_post(&post.get_ap_id()?, context, request_counter) // TODO: why?
.await? let original_post_id =
.id; get_or_fetch_and_insert_post(&Url::parse(&post.ap_id)?, context, request_counter)
.await?
blocking(context.pool(), move |conn| { .id;
Post::update(conn, original_post_id, &post)
})
.await??;
// Refetch the view // Refetch the view
let post_view = blocking(context.pool(), move |conn| { let post_view = blocking(context.pool(), move |conn| {
@ -99,9 +92,10 @@ pub(crate) async fn receive_like_post(
let page = PageExt::from_any_base(like.object().to_owned().one().context(location_info!())?)? let page = PageExt::from_any_base(like.object().to_owned().one().context(location_info!())?)?
.context(location_info!())?; .context(location_info!())?;
let post = PostForm::from_apub(&page, context, None, request_counter).await?; let post = Post::from_apub(&page, context, None, request_counter).await?;
let post_id = get_or_fetch_and_insert_post(&post.get_ap_id()?, context, request_counter) // TODO: why?
let post_id = get_or_fetch_and_insert_post(&Url::parse(&post.ap_id)?, context, request_counter)
.await? .await?
.id; .id;
@ -149,9 +143,9 @@ pub(crate) async fn receive_dislike_post(
)? )?
.context(location_info!())?; .context(location_info!())?;
let post = PostForm::from_apub(&page, context, None, request_counter).await?; let post = Post::from_apub(&page, context, None, request_counter).await?;
let post_id = get_or_fetch_and_insert_post(&post.get_ap_id()?, context, request_counter) let post_id = get_or_fetch_and_insert_post(&Url::parse(&post.ap_id)?, context, request_counter)
.await? .await?
.id; .id;

View file

@ -1,19 +1,20 @@
use crate::{ use crate::{
activities::receive::get_actor_as_user, activities::receive::get_actor_as_user,
fetcher::get_or_fetch_and_insert_post, fetcher::get_or_fetch_and_insert_post,
objects::FromApub,
PageExt, PageExt,
}; };
use crate::objects::FromApub;
use activitystreams::{activity::*, prelude::*}; use activitystreams::{activity::*, prelude::*};
use anyhow::Context; use anyhow::Context;
use lemmy_db::{ use lemmy_db::{
post::{Post, PostForm, PostLike}, post::{Post, PostLike},
post_view::PostView, post_view::PostView,
Likeable, Likeable,
}; };
use lemmy_structs::{blocking, post::PostResponse}; use lemmy_structs::{blocking, post::PostResponse};
use lemmy_utils::{location_info, LemmyError}; use lemmy_utils::{location_info, LemmyError};
use lemmy_websocket::{messages::SendPost, LemmyContext, UserOperation}; use lemmy_websocket::{messages::SendPost, LemmyContext, UserOperation};
use url::Url;
pub(crate) async fn receive_undo_like_post( pub(crate) async fn receive_undo_like_post(
like: &Like, like: &Like,
@ -24,9 +25,10 @@ pub(crate) async fn receive_undo_like_post(
let page = PageExt::from_any_base(like.object().to_owned().one().context(location_info!())?)? let page = PageExt::from_any_base(like.object().to_owned().one().context(location_info!())?)?
.context(location_info!())?; .context(location_info!())?;
let post = PostForm::from_apub(&page, context, None, request_counter).await?; let post = Post::from_apub(&page, context, None, request_counter).await?;
let post_id = get_or_fetch_and_insert_post(&post.get_ap_id()?, context, request_counter) // TODO: why?
let post_id = get_or_fetch_and_insert_post(&Url::parse(&post.ap_id)?, context, request_counter)
.await? .await?
.id; .id;
@ -68,9 +70,10 @@ pub(crate) async fn receive_undo_dislike_post(
)? )?
.context(location_info!())?; .context(location_info!())?;
let post = PostForm::from_apub(&page, context, None, request_counter).await?; let post = Post::from_apub(&page, context, None, request_counter).await?;
let post_id = get_or_fetch_and_insert_post(&post.get_ap_id()?, context, request_counter) // TODO: why?
let post_id = get_or_fetch_and_insert_post(&Url::parse(&post.ap_id)?, context, request_counter)
.await? .await?
.id; .id;

View file

@ -3,9 +3,9 @@ use crate::{
check_is_apub_id_valid, check_is_apub_id_valid,
fetcher::get_or_fetch_and_upsert_user, fetcher::get_or_fetch_and_upsert_user,
inbox::get_activity_to_and_cc, inbox::get_activity_to_and_cc,
objects::FromApub,
NoteExt, NoteExt,
}; };
use crate::objects::FromApub;
use activitystreams::{ use activitystreams::{
activity::{ActorAndObjectRefExt, Create, Delete, Undo, Update}, activity::{ActorAndObjectRefExt, Create, Delete, Undo, Update},
base::{AsBase, ExtendsExt}, base::{AsBase, ExtendsExt},
@ -13,11 +13,7 @@ use activitystreams::{
public, public,
}; };
use anyhow::{anyhow, Context}; use anyhow::{anyhow, Context};
use lemmy_db::{ use lemmy_db::{private_message::PrivateMessage, private_message_view::PrivateMessageView};
private_message::{PrivateMessage, PrivateMessageForm},
private_message_view::PrivateMessageView,
Crud,
};
use lemmy_structs::{blocking, user::PrivateMessageResponse}; use lemmy_structs::{blocking, user::PrivateMessageResponse};
use lemmy_utils::{location_info, LemmyError}; use lemmy_utils::{location_info, LemmyError};
use lemmy_websocket::{messages::SendUserRoomMessage, LemmyContext, UserOperation}; use lemmy_websocket::{messages::SendUserRoomMessage, LemmyContext, UserOperation};
@ -41,15 +37,10 @@ pub(crate) async fn receive_create_private_message(
.context(location_info!())?; .context(location_info!())?;
let private_message = let private_message =
PrivateMessageForm::from_apub(&note, context, Some(expected_domain), request_counter).await?; PrivateMessage::from_apub(&note, context, Some(expected_domain), request_counter).await?;
let inserted_private_message = blocking(&context.pool(), move |conn| {
PrivateMessage::create(conn, &private_message)
})
.await??;
let message = blocking(&context.pool(), move |conn| { let message = blocking(&context.pool(), move |conn| {
PrivateMessageView::read(conn, inserted_private_message.id) PrivateMessageView::read(conn, private_message.id)
}) })
.await??; .await??;
@ -82,24 +73,8 @@ pub(crate) async fn receive_update_private_message(
.to_owned(); .to_owned();
let note = NoteExt::from_any_base(object)?.context(location_info!())?; let note = NoteExt::from_any_base(object)?.context(location_info!())?;
let private_message_form = let private_message =
PrivateMessageForm::from_apub(&note, context, Some(expected_domain), request_counter).await?; PrivateMessage::from_apub(&note, context, Some(expected_domain), request_counter).await?;
let private_message_ap_id = private_message_form
.ap_id
.as_ref()
.context(location_info!())?
.clone();
let private_message = blocking(&context.pool(), move |conn| {
PrivateMessage::read_from_apub_id(conn, &private_message_ap_id)
})
.await??;
let private_message_id = private_message.id;
blocking(&context.pool(), move |conn| {
PrivateMessage::update(conn, private_message_id, &private_message_form)
})
.await??;
let private_message_id = private_message.id; let private_message_id = private_message.id;
let message = blocking(&context.pool(), move |conn| { let message = blocking(&context.pool(), move |conn| {

View file

@ -3,6 +3,7 @@ use crate::{
activity_queue::{send_comment_mentions, send_to_community}, activity_queue::{send_comment_mentions, send_to_community},
extensions::context::lemmy_context, extensions::context::lemmy_context,
fetcher::get_or_fetch_and_upsert_user, fetcher::get_or_fetch_and_upsert_user,
objects::ToApub,
ActorType, ActorType,
ApubLikeableType, ApubLikeableType,
ApubObjectType, ApubObjectType,
@ -38,7 +39,6 @@ use log::debug;
use reqwest::Client; use reqwest::Client;
use serde_json::Error; use serde_json::Error;
use url::Url; use url::Url;
use crate::objects::ToApub;
#[async_trait::async_trait(?Send)] #[async_trait::async_trait(?Send)]
impl ApubObjectType for Comment { impl ApubObjectType for Comment {

View file

@ -2,11 +2,11 @@ use crate::{
activities::send::generate_activity_id, activities::send::generate_activity_id,
activity_queue::send_to_community, activity_queue::send_to_community,
extensions::context::lemmy_context, extensions::context::lemmy_context,
objects::ToApub,
ActorType, ActorType,
ApubLikeableType, ApubLikeableType,
ApubObjectType, ApubObjectType,
}; };
use crate::objects::ToApub;
use activitystreams::{ use activitystreams::{
activity::{ activity::{
kind::{CreateType, DeleteType, DislikeType, LikeType, RemoveType, UndoType, UpdateType}, kind::{CreateType, DeleteType, DislikeType, LikeType, RemoveType, UndoType, UpdateType},

View file

@ -2,10 +2,10 @@ use crate::{
activities::send::generate_activity_id, activities::send::generate_activity_id,
activity_queue::send_activity_single_dest, activity_queue::send_activity_single_dest,
extensions::context::lemmy_context, extensions::context::lemmy_context,
objects::ToApub,
ActorType, ActorType,
ApubObjectType, ApubObjectType,
}; };
use crate::objects::ToApub;
use activitystreams::{ use activitystreams::{
activity::{ activity::{
kind::{CreateType, DeleteType, UndoType, UpdateType}, kind::{CreateType, DeleteType, UndoType, UpdateType},

View file

@ -1,5 +1,6 @@
use crate::{ use crate::{
check_is_apub_id_valid, check_is_apub_id_valid,
objects::FromApub,
ActorType, ActorType,
GroupExt, GroupExt,
NoteExt, NoteExt,
@ -12,16 +13,15 @@ use anyhow::{anyhow, Context};
use chrono::NaiveDateTime; use chrono::NaiveDateTime;
use diesel::result::Error::NotFound; use diesel::result::Error::NotFound;
use lemmy_db::{ use lemmy_db::{
comment::{Comment, CommentForm}, comment::Comment,
comment_view::CommentView, comment_view::CommentView,
community::{Community, CommunityForm, CommunityModerator, CommunityModeratorForm}, community::{Community, CommunityModerator, CommunityModeratorForm},
community_view::CommunityView, community_view::CommunityView,
naive_now, naive_now,
post::{Post, PostForm}, post::Post,
post_view::PostView, post_view::PostView,
user::{UserForm, User_}, user::User_,
user_view::UserView, user_view::UserView,
Crud,
Joinable, Joinable,
SearchType, SearchType,
}; };
@ -38,7 +38,6 @@ use reqwest::Client;
use serde::Deserialize; use serde::Deserialize;
use std::{fmt::Debug, time::Duration}; use std::{fmt::Debug, time::Duration};
use url::Url; use url::Url;
use crate::objects::FromApub;
static ACTOR_REFETCH_INTERVAL_SECONDS: i64 = 24 * 60 * 60; static ACTOR_REFETCH_INTERVAL_SECONDS: i64 = 24 * 60 * 60;
static ACTOR_REFETCH_INTERVAL_SECONDS_DEBUG: i64 = 10; static ACTOR_REFETCH_INTERVAL_SECONDS_DEBUG: i64 = 10;
@ -184,22 +183,16 @@ pub async fn search_by_apub_id(
response response
} }
SearchAcceptedObjects::Page(p) => { SearchAcceptedObjects::Page(p) => {
let post_form = PostForm::from_apub(&p, context, Some(query_url), recursion_counter).await?; let p = Post::from_apub(&p, context, Some(query_url), recursion_counter).await?;
let p = blocking(context.pool(), move |conn| Post::upsert(conn, &post_form)).await??;
response.posts = response.posts =
vec![blocking(context.pool(), move |conn| PostView::read(conn, p.id, None)).await??]; vec![blocking(context.pool(), move |conn| PostView::read(conn, p.id, None)).await??];
response response
} }
SearchAcceptedObjects::Comment(c) => { SearchAcceptedObjects::Comment(c) => {
let comment_form = let c = Comment::from_apub(&c, context, Some(query_url), recursion_counter).await?;
CommentForm::from_apub(&c, context, Some(query_url), recursion_counter).await?;
let c = blocking(context.pool(), move |conn| {
Comment::upsert(conn, &comment_form)
})
.await??;
response.comments = vec![ response.comments = vec![
blocking(context.pool(), move |conn| { blocking(context.pool(), move |conn| {
CommentView::read(conn, c.id, None) CommentView::read(conn, c.id, None)
@ -258,15 +251,15 @@ pub(crate) async fn get_or_fetch_and_upsert_user(
return Ok(u); return Ok(u);
} }
let mut uf = UserForm::from_apub( let user = User_::from_apub(
&person?, &person?,
context, context,
Some(apub_id.to_owned()), Some(apub_id.to_owned()),
recursion_counter, recursion_counter,
) )
.await?; .await?;
uf.last_refreshed_at = Some(naive_now()); // TODO: do we need to set this? would need a separate db call
let user = blocking(context.pool(), move |conn| User_::update(conn, u.id, &uf)).await??; //uf.last_refreshed_at = Some(naive_now());
Ok(user) Ok(user)
} }
@ -276,14 +269,13 @@ pub(crate) async fn get_or_fetch_and_upsert_user(
let person = let person =
fetch_remote_object::<PersonExt>(context.client(), apub_id, recursion_counter).await?; fetch_remote_object::<PersonExt>(context.client(), apub_id, recursion_counter).await?;
let uf = UserForm::from_apub( let user = User_::from_apub(
&person, &person,
context, context,
Some(apub_id.to_owned()), Some(apub_id.to_owned()),
recursion_counter, recursion_counter,
) )
.await?; .await?;
let user = blocking(context.pool(), move |conn| User_::upsert(conn, &uf)).await??;
Ok(user) Ok(user)
} }
@ -354,9 +346,8 @@ async fn fetch_remote_community(
} }
let group = group?; let group = group?;
let cf = let community =
CommunityForm::from_apub(&group, context, Some(apub_id.to_owned()), recursion_counter).await?; Community::from_apub(&group, context, Some(apub_id.to_owned()), recursion_counter).await?;
let community = blocking(context.pool(), move |conn| Community::upsert(conn, &cf)).await??;
// Also add the community moderators too // Also add the community moderators too
let attributed_to = group.inner.attributed_to().context(location_info!())?; let attributed_to = group.inner.attributed_to().context(location_info!())?;
@ -409,20 +400,10 @@ async fn fetch_remote_community(
// The post creator may be from a blocked instance, // The post creator may be from a blocked instance,
// if it errors, then continue // if it errors, then continue
let post = match PostForm::from_apub(&page, context, None, recursion_counter).await { match Post::from_apub(&page, context, None, recursion_counter).await {
Ok(post) => post, Ok(post) => post,
Err(_) => continue, Err(_) => continue,
}; };
let post_ap_id = post.ap_id.as_ref().context(location_info!())?.clone();
// Check whether the post already exists in the local db
let existing = blocking(context.pool(), move |conn| {
Post::read_from_apub_id(conn, &post_ap_id)
})
.await?;
match existing {
Ok(e) => blocking(context.pool(), move |conn| Post::update(conn, e.id, &post)).await??,
Err(_) => blocking(context.pool(), move |conn| Post::upsert(conn, &post)).await??,
};
// TODO: we need to send a websocket update here // TODO: we need to send a websocket update here
} }
@ -448,18 +429,16 @@ pub(crate) async fn get_or_fetch_and_insert_post(
Ok(p) => Ok(p), Ok(p) => Ok(p),
Err(NotFound {}) => { Err(NotFound {}) => {
debug!("Fetching and creating remote post: {}", post_ap_id); debug!("Fetching and creating remote post: {}", post_ap_id);
let post = let page =
fetch_remote_object::<PageExt>(context.client(), post_ap_id, recursion_counter).await?; fetch_remote_object::<PageExt>(context.client(), post_ap_id, recursion_counter).await?;
let post_form = PostForm::from_apub( let post = Post::from_apub(
&post, &page,
context, context,
Some(post_ap_id.to_owned()), Some(post_ap_id.to_owned()),
recursion_counter, recursion_counter,
) )
.await?; .await?;
let post = blocking(context.pool(), move |conn| Post::upsert(conn, &post_form)).await??;
Ok(post) Ok(post)
} }
Err(e) => Err(e.into()), Err(e) => Err(e.into()),
@ -490,7 +469,7 @@ pub(crate) async fn get_or_fetch_and_insert_comment(
); );
let comment = let comment =
fetch_remote_object::<NoteExt>(context.client(), comment_ap_id, recursion_counter).await?; fetch_remote_object::<NoteExt>(context.client(), comment_ap_id, recursion_counter).await?;
let comment_form = CommentForm::from_apub( let comment = Comment::from_apub(
&comment, &comment,
context, context,
Some(comment_ap_id.to_owned()), Some(comment_ap_id.to_owned()),
@ -498,17 +477,12 @@ pub(crate) async fn get_or_fetch_and_insert_comment(
) )
.await?; .await?;
let post_id = comment_form.post_id; let post_id = comment.post_id;
let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??; let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
if post.locked { if post.locked {
return Err(anyhow!("Post is locked").into()); return Err(anyhow!("Post is locked").into());
} }
let comment = blocking(context.pool(), move |conn| {
Comment::upsert(conn, &comment_form)
})
.await??;
Ok(comment) Ok(comment)
} }
Err(e) => Err(e.into()), Err(e) => Err(e.into()),

View file

@ -1,5 +1,6 @@
use crate::{ use crate::{
http::{create_apub_response, create_apub_tombstone_response}, http::{create_apub_response, create_apub_tombstone_response},
objects::ToApub,
}; };
use actix_web::{body::Body, web, web::Path, HttpResponse}; use actix_web::{body::Body, web, web::Path, HttpResponse};
use diesel::result::Error::NotFound; use diesel::result::Error::NotFound;
@ -8,7 +9,6 @@ use lemmy_structs::blocking;
use lemmy_utils::LemmyError; use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext; use lemmy_websocket::LemmyContext;
use serde::Deserialize; use serde::Deserialize;
use crate::objects::ToApub;
#[derive(Deserialize)] #[derive(Deserialize)]
pub struct CommentQuery { pub struct CommentQuery {

View file

@ -1,6 +1,7 @@
use crate::{ use crate::{
extensions::context::lemmy_context, extensions::context::lemmy_context,
http::{create_apub_response, create_apub_tombstone_response}, http::{create_apub_response, create_apub_tombstone_response},
objects::ToApub,
ActorType, ActorType,
}; };
use activitystreams::{ use activitystreams::{
@ -13,7 +14,6 @@ use lemmy_structs::blocking;
use lemmy_utils::LemmyError; use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext; use lemmy_websocket::LemmyContext;
use serde::Deserialize; use serde::Deserialize;
use crate::objects::ToApub;
#[derive(Deserialize)] #[derive(Deserialize)]
pub struct CommunityQuery { pub struct CommunityQuery {

View file

@ -1,5 +1,6 @@
use crate::{ use crate::{
http::{create_apub_response, create_apub_tombstone_response}, http::{create_apub_response, create_apub_tombstone_response},
objects::ToApub,
}; };
use actix_web::{body::Body, web, HttpResponse}; use actix_web::{body::Body, web, HttpResponse};
use diesel::result::Error::NotFound; use diesel::result::Error::NotFound;
@ -8,7 +9,6 @@ use lemmy_structs::blocking;
use lemmy_utils::LemmyError; use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext; use lemmy_websocket::LemmyContext;
use serde::Deserialize; use serde::Deserialize;
use crate::objects::ToApub;
#[derive(Deserialize)] #[derive(Deserialize)]
pub struct PostQuery { pub struct PostQuery {

View file

@ -1,9 +1,13 @@
use crate::{extensions::context::lemmy_context, http::create_apub_response, ActorType}; use crate::{
extensions::context::lemmy_context,
http::create_apub_response,
objects::ToApub,
ActorType,
};
use activitystreams::{ use activitystreams::{
base::BaseExt, base::BaseExt,
collection::{CollectionExt, OrderedCollection}, collection::{CollectionExt, OrderedCollection},
}; };
use crate::objects::ToApub;
use actix_web::{body::Body, web, HttpResponse}; use actix_web::{body::Body, web, HttpResponse};
use lemmy_db::user::User_; use lemmy_db::user::User_;
use lemmy_structs::blocking; use lemmy_structs::blocking;

View file

@ -10,6 +10,9 @@ use crate::{
create_tombstone, create_tombstone,
get_source_markdown_value, get_source_markdown_value,
set_content_and_source, set_content_and_source,
FromApub,
FromApubToForm,
ToApub,
}, },
NoteExt, NoteExt,
}; };
@ -29,13 +32,12 @@ use lemmy_db::{
use lemmy_structs::blocking; use lemmy_structs::blocking;
use lemmy_utils::{ use lemmy_utils::{
location_info, location_info,
settings::Settings,
utils::{convert_datetime, remove_slurs}, utils::{convert_datetime, remove_slurs},
LemmyError, LemmyError,
}; };
use lemmy_websocket::LemmyContext; use lemmy_websocket::LemmyContext;
use url::Url; use url::Url;
use crate::objects::{FromApub, ToApub, FromApubToForm};
use lemmy_utils::settings::Settings;
#[async_trait::async_trait(?Send)] #[async_trait::async_trait(?Send)]
impl ToApub for Comment { impl ToApub for Comment {
@ -99,20 +101,23 @@ impl FromApub for Comment {
expected_domain: Option<Url>, expected_domain: Option<Url>,
request_counter: &mut i32, request_counter: &mut i32,
) -> Result<Comment, LemmyError> { ) -> Result<Comment, LemmyError> {
let comment_id = note.id_unchecked().context(location_info!())?; // TODO: we should move read_from_apub_id() and upsert() into traits so we can make a generic
// function to handle all this (shared with User_::from_apub etc)
let comment_id = note.id_unchecked().context(location_info!())?.to_owned();
let domain = comment_id.domain().context(location_info!())?; let domain = comment_id.domain().context(location_info!())?;
if domain == Settings::get().hostname { if domain == Settings::get().hostname {
let comment = blocking(context.pool(), move |conn| { let comment = blocking(context.pool(), move |conn| {
Comment::read_from_apub_id(conn, comment_id.as_str()) Comment::read_from_apub_id(conn, comment_id.as_str())
}) })
.await??; .await??;
Ok(comment) Ok(comment)
} else { } else {
let comment_form = CommentForm::from_apub(note, context, expected_domain, request_counter)?; let comment_form =
CommentForm::from_apub(note, context, expected_domain, request_counter).await?;
let comment = blocking(context.pool(), move |conn| { let comment = blocking(context.pool(), move |conn| {
Comment::upsert(conn, comment_form) Comment::upsert(conn, &comment_form)
}) })
.await??; .await??;
Ok(comment) Ok(comment)
} }
} }

View file

@ -6,6 +6,9 @@ use crate::{
create_tombstone, create_tombstone,
get_source_markdown_value, get_source_markdown_value,
set_content_and_source, set_content_and_source,
FromApub,
FromApubToForm,
ToApub,
}, },
ActorType, ActorType,
GroupExt, GroupExt,
@ -27,10 +30,10 @@ use lemmy_db::{
use lemmy_structs::blocking; use lemmy_structs::blocking;
use lemmy_utils::{ use lemmy_utils::{
location_info, location_info,
settings::Settings,
utils::{check_slurs, check_slurs_opt, convert_datetime}, utils::{check_slurs, check_slurs_opt, convert_datetime},
LemmyError, LemmyError,
}; };
use crate::objects::{FromApub, ToApub, FromApubToForm};
use lemmy_websocket::LemmyContext; use lemmy_websocket::LemmyContext;
use url::Url; use url::Url;
@ -117,7 +120,23 @@ impl FromApub for Community {
expected_domain: Option<Url>, expected_domain: Option<Url>,
request_counter: &mut i32, request_counter: &mut i32,
) -> Result<Community, LemmyError> { ) -> Result<Community, LemmyError> {
todo!() let community_id = group.id_unchecked().context(location_info!())?.to_owned();
let domain = community_id.domain().context(location_info!())?;
if domain == Settings::get().hostname {
let community = blocking(context.pool(), move |conn| {
Community::read_from_actor_id(conn, community_id.as_str())
})
.await??;
Ok(community)
} else {
let community_form =
CommunityForm::from_apub(group, context, expected_domain, request_counter).await?;
let community = blocking(context.pool(), move |conn| {
Community::upsert(conn, &community_form)
})
.await??;
Ok(community)
}
} }
} }

View file

@ -7,10 +7,10 @@ use activitystreams::{
}; };
use anyhow::{anyhow, Context}; use anyhow::{anyhow, Context};
use chrono::NaiveDateTime; use chrono::NaiveDateTime;
use lemmy_utils::{location_info, utils::convert_datetime, LemmyError};
use url::Url;
use lemmy_websocket::LemmyContext;
use lemmy_db::DbPool; use lemmy_db::DbPool;
use lemmy_utils::{location_info, utils::convert_datetime, LemmyError};
use lemmy_websocket::LemmyContext;
use url::Url;
pub(crate) mod comment; pub(crate) mod comment;
pub(crate) mod community; pub(crate) mod community;
@ -41,8 +41,8 @@ pub(crate) trait FromApub {
expected_domain: Option<Url>, expected_domain: Option<Url>,
request_counter: &mut i32, request_counter: &mut i32,
) -> Result<Self, LemmyError> ) -> Result<Self, LemmyError>
where where
Self: Sized; Self: Sized;
} }
#[async_trait::async_trait(?Send)] #[async_trait::async_trait(?Send)]
@ -54,8 +54,8 @@ pub(in crate::objects) trait FromApubToForm {
expected_domain: Option<Url>, expected_domain: Option<Url>,
request_counter: &mut i32, request_counter: &mut i32,
) -> Result<Self, LemmyError> ) -> Result<Self, LemmyError>
where where
Self: Sized; Self: Sized;
} }
/// Updated is actually the deletion time /// Updated is actually the deletion time

View file

@ -6,6 +6,9 @@ use crate::{
create_tombstone, create_tombstone,
get_source_markdown_value, get_source_markdown_value,
set_content_and_source, set_content_and_source,
FromApub,
FromApubToForm,
ToApub,
}, },
PageExt, PageExt,
}; };
@ -27,13 +30,13 @@ use lemmy_structs::blocking;
use lemmy_utils::{ use lemmy_utils::{
location_info, location_info,
request::fetch_iframely_and_pictrs_data, request::fetch_iframely_and_pictrs_data,
settings::Settings,
utils::{check_slurs, convert_datetime, remove_slurs}, utils::{check_slurs, convert_datetime, remove_slurs},
LemmyError, LemmyError,
}; };
use lemmy_websocket::LemmyContext; use lemmy_websocket::LemmyContext;
use log::error; use log::error;
use url::Url; use url::Url;
use crate::objects::{FromApubToForm, ToApub, FromApub};
#[async_trait::async_trait(?Send)] #[async_trait::async_trait(?Send)]
impl ToApub for Post { impl ToApub for Post {
@ -104,12 +107,24 @@ impl FromApub for Post {
/// ///
/// If the post's community or creator are not known locally, these are also fetched. /// If the post's community or creator are not known locally, these are also fetched.
async fn from_apub( async fn from_apub(
note: &PageExt, page: &PageExt,
context: &LemmyContext, context: &LemmyContext,
expected_domain: Option<Url>, expected_domain: Option<Url>,
request_counter: &mut i32, request_counter: &mut i32,
) -> Result<Post, LemmyError> { ) -> Result<Post, LemmyError> {
todo!() let post_id = page.id_unchecked().context(location_info!())?.to_owned();
let domain = post_id.domain().context(location_info!())?;
if domain == Settings::get().hostname {
let post = blocking(context.pool(), move |conn| {
Post::read_from_apub_id(conn, post_id.as_str())
})
.await??;
Ok(post)
} else {
let post_form = PostForm::from_apub(page, context, expected_domain, request_counter).await?;
let post = blocking(context.pool(), move |conn| Post::upsert(conn, &post_form)).await??;
Ok(post)
}
} }
} }

View file

@ -7,10 +7,12 @@ use crate::{
create_tombstone, create_tombstone,
get_source_markdown_value, get_source_markdown_value,
set_content_and_source, set_content_and_source,
FromApub,
FromApubToForm,
ToApub,
}, },
NoteExt, NoteExt,
}; };
use crate::objects::{FromApubToForm, ToApub, FromApub};
use activitystreams::{ use activitystreams::{
object::{kind::NoteType, ApObject, Note, Tombstone}, object::{kind::NoteType, ApObject, Note, Tombstone},
prelude::*, prelude::*,
@ -23,7 +25,7 @@ use lemmy_db::{
DbPool, DbPool,
}; };
use lemmy_structs::blocking; use lemmy_structs::blocking;
use lemmy_utils::{location_info, utils::convert_datetime, LemmyError}; use lemmy_utils::{location_info, settings::Settings, utils::convert_datetime, LemmyError};
use lemmy_websocket::LemmyContext; use lemmy_websocket::LemmyContext;
use url::Url; use url::Url;
@ -71,7 +73,23 @@ impl FromApub for PrivateMessage {
expected_domain: Option<Url>, expected_domain: Option<Url>,
request_counter: &mut i32, request_counter: &mut i32,
) -> Result<PrivateMessage, LemmyError> { ) -> Result<PrivateMessage, LemmyError> {
todo!() let private_message_id = note.id_unchecked().context(location_info!())?.to_owned();
let domain = private_message_id.domain().context(location_info!())?;
if domain == Settings::get().hostname {
let private_message = blocking(context.pool(), move |conn| {
PrivateMessage::read_from_apub_id(conn, private_message_id.as_str())
})
.await??;
Ok(private_message)
} else {
let private_message_form =
PrivateMessageForm::from_apub(note, context, expected_domain, request_counter).await?;
let private_message = blocking(context.pool(), move |conn| {
PrivateMessage::upsert(conn, &private_message_form)
})
.await??;
Ok(private_message)
}
} }
} }

View file

@ -1,10 +1,16 @@
use crate::{ use crate::{
extensions::context::lemmy_context, extensions::context::lemmy_context,
objects::{check_object_domain, get_source_markdown_value, set_content_and_source}, objects::{
check_object_domain,
get_source_markdown_value,
set_content_and_source,
FromApub,
FromApubToForm,
ToApub,
},
ActorType, ActorType,
PersonExt, PersonExt,
}; };
use crate::objects::{FromApubToForm, ToApub, FromApub};
use activitystreams::{ use activitystreams::{
actor::{ApActor, Endpoints, Person}, actor::{ApActor, Endpoints, Person},
object::{ApObject, Image, Tombstone}, object::{ApObject, Image, Tombstone},
@ -17,8 +23,10 @@ use lemmy_db::{
user::{UserForm, User_}, user::{UserForm, User_},
DbPool, DbPool,
}; };
use lemmy_structs::blocking;
use lemmy_utils::{ use lemmy_utils::{
location_info, location_info,
settings::Settings,
utils::{check_slurs, check_slurs_opt, convert_datetime}, utils::{check_slurs, check_slurs_opt, convert_datetime},
LemmyError, LemmyError,
}; };
@ -84,12 +92,25 @@ impl FromApub for User_ {
type ApubType = PersonExt; type ApubType = PersonExt;
async fn from_apub( async fn from_apub(
note: &PersonExt, person: &PersonExt,
context: &LemmyContext, context: &LemmyContext,
expected_domain: Option<Url>, expected_domain: Option<Url>,
request_counter: &mut i32, request_counter: &mut i32,
) -> Result<User_, LemmyError> { ) -> Result<User_, LemmyError> {
todo!() let user_id = person.id_unchecked().context(location_info!())?.to_owned();
let domain = user_id.domain().context(location_info!())?;
if domain == Settings::get().hostname {
let user = blocking(context.pool(), move |conn| {
User_::read_from_actor_id(conn, user_id.as_str())
})
.await??;
Ok(user)
} else {
let user_form =
UserForm::from_apub(person, context, expected_domain, request_counter).await?;
let user = blocking(context.pool(), move |conn| User_::upsert(conn, &user_form)).await??;
Ok(user)
}
} }
} }