X-Git-Url: http://these/git/?a=blobdiff_plain;f=crates%2Fapi_crud%2Fsrc%2Fpost%2Fread.rs;h=d37b1a5825819cb875325cbb9b6660fab312d72e;hb=c8063f3267cf2b3622f1fdc69128c6b55feefbbc;hp=a59e8197b45cb037e27223d833ce65cf5a0d7fec;hpb=0aeb78b8f39f777cd5d1af292258897964e58f2a;p=lemmy.git diff --git a/crates/api_crud/src/post/read.rs b/crates/api_crud/src/post/read.rs index a59e8197..d37b1a58 100644 --- a/crates/api_crud/src/post/read.rs +++ b/crates/api_crud/src/post/read.rs @@ -1,115 +1,115 @@ -use crate::PerformCrud; -use actix_web::web::Data; +use actix_web::web::{Data, Json, Query}; use lemmy_api_common::{ + context::LemmyContext, post::{GetPost, GetPostResponse}, - utils::{blocking, check_private_instance, get_local_user_view_from_jwt_opt, mark_post_as_read}, + utils::{ + check_private_instance, + is_mod_or_admin_opt, + local_user_view_from_jwt_opt, + mark_post_as_read, + }, }; use lemmy_db_schema::{ aggregates::structs::{PersonPostAggregates, PersonPostAggregatesForm}, - source::comment::Comment, - traits::{Crud, DeleteableOrRemoveable}, + source::{comment::Comment, local_site::LocalSite, post::Post}, + traits::Crud, }; -use lemmy_db_views::structs::PostView; +use lemmy_db_views::{post_view::PostQuery, structs::PostView}; use lemmy_db_views_actor::structs::{CommunityModeratorView, CommunityView}; -use lemmy_utils::{error::LemmyError, ConnectionId}; -use lemmy_websocket::{messages::GetPostUsersOnline, LemmyContext}; +use lemmy_utils::error::{LemmyError, LemmyErrorExt, LemmyErrorType}; -#[async_trait::async_trait(?Send)] -impl PerformCrud for GetPost { - type Response = GetPostResponse; +#[tracing::instrument(skip(context))] +pub async fn get_post( + data: Query, + context: Data, +) -> Result, LemmyError> { + let local_user_view = local_user_view_from_jwt_opt(data.auth.as_ref(), &context).await; + let local_site = LocalSite::read(&mut context.pool()).await?; - #[tracing::instrument(skip(context, _websocket_id))] - async fn perform( - &self, - context: &Data, - _websocket_id: Option, - ) -> Result { - let data: &GetPost = self; - let local_user_view = - get_local_user_view_from_jwt_opt(data.auth.as_ref(), context.pool(), context.secret()) - .await?; + check_private_instance(&local_user_view, &local_site)?; - check_private_instance(&local_user_view, context.pool()).await?; + let person_id = local_user_view.as_ref().map(|u| u.person.id); - let person_id = local_user_view.map(|u| u.person.id); + // I'd prefer fetching the post_view by a comment join, but it adds a lot of boilerplate + let post_id = if let Some(id) = data.id { + id + } else if let Some(comment_id) = data.comment_id { + Comment::read(&mut context.pool(), comment_id) + .await + .with_lemmy_type(LemmyErrorType::CouldntFindPost)? + .post_id + } else { + Err(LemmyErrorType::CouldntFindPost)? + }; - // I'd prefer fetching the post_view by a comment join, but it adds a lot of boilerplate - let post_id = if let Some(id) = data.id { - id - } else if let Some(comment_id) = data.comment_id { - blocking(context.pool(), move |conn| Comment::read(conn, comment_id)) - .await? - .map_err(|e| LemmyError::from_error_message(e, "couldnt_find_post"))? - .post_id - } else { - Err(LemmyError::from_message("couldnt_find_post"))? - }; + // Check to see if the person is a mod or admin, to show deleted / removed + let community_id = Post::read(&mut context.pool(), post_id).await?.community_id; + let is_mod_or_admin = is_mod_or_admin_opt( + &mut context.pool(), + local_user_view.as_ref(), + Some(community_id), + ) + .await + .is_ok(); - let mut post_view = blocking(context.pool(), move |conn| { - PostView::read(conn, post_id, person_id) - }) - .await? - .map_err(|e| LemmyError::from_error_message(e, "couldnt_find_post"))?; + let post_view = PostView::read(&mut context.pool(), post_id, person_id, is_mod_or_admin) + .await + .with_lemmy_type(LemmyErrorType::CouldntFindPost)?; - // Mark the post as read - let post_id = post_view.post.id; - if let Some(person_id) = person_id { - mark_post_as_read(person_id, post_id, context.pool()).await?; - } + // Mark the post as read + let post_id = post_view.post.id; + if let Some(person_id) = person_id { + mark_post_as_read(person_id, post_id, &mut context.pool()).await?; + } - // Necessary for the sidebar subscribed - let community_id = post_view.community.id; - let mut community_view = blocking(context.pool(), move |conn| { - CommunityView::read(conn, community_id, person_id) - }) - .await? - .map_err(|e| LemmyError::from_error_message(e, "couldnt_find_community"))?; + // Necessary for the sidebar subscribed + let community_view = CommunityView::read( + &mut context.pool(), + community_id, + person_id, + is_mod_or_admin, + ) + .await + .with_lemmy_type(LemmyErrorType::CouldntFindCommunity)?; - // Insert into PersonPostAggregates - // to update the read_comments count - if let Some(person_id) = person_id { - let read_comments = post_view.counts.comments; - let person_post_agg_form = PersonPostAggregatesForm { - person_id, - post_id, - read_comments, - ..PersonPostAggregatesForm::default() - }; - blocking(context.pool(), move |conn| { - PersonPostAggregates::upsert(conn, &person_post_agg_form) - }) - .await? - .map_err(|e| LemmyError::from_error_message(e, "couldnt_find_post"))?; - } + // Insert into PersonPostAggregates + // to update the read_comments count + if let Some(person_id) = person_id { + let read_comments = post_view.counts.comments; + let person_post_agg_form = PersonPostAggregatesForm { + person_id, + post_id, + read_comments, + ..PersonPostAggregatesForm::default() + }; + PersonPostAggregates::upsert(&mut context.pool(), &person_post_agg_form) + .await + .with_lemmy_type(LemmyErrorType::CouldntFindPost)?; + } - // Blank out deleted or removed info for non-logged in users - if person_id.is_none() { - if post_view.post.deleted || post_view.post.removed { - post_view.post = post_view.post.blank_out_deleted_or_removed_info(); - } + let moderators = CommunityModeratorView::for_community(&mut context.pool(), community_id).await?; - if community_view.community.deleted || community_view.community.removed { - community_view.community = community_view.community.blank_out_deleted_or_removed_info(); - } + // Fetch the cross_posts + let cross_posts = if let Some(url) = &post_view.post.url { + let mut x_posts = PostQuery { + url_search: Some(url.inner().as_str().into()), + ..Default::default() } + .list(&mut context.pool()) + .await?; - let moderators = blocking(context.pool(), move |conn| { - CommunityModeratorView::for_community(conn, community_id) - }) - .await??; + // Don't return this post as one of the cross_posts + x_posts.retain(|x| x.post.id != post_id); + x_posts + } else { + Vec::new() + }; - let online = context - .chat_server() - .send(GetPostUsersOnline { post_id }) - .await - .unwrap_or(1); - - // Return the jwt - Ok(GetPostResponse { - post_view, - community_view, - moderators, - online, - }) - } + // Return the jwt + Ok(Json(GetPostResponse { + post_view, + community_view, + moderators, + cross_posts, + })) }