lemmy/crates/api_crud/src/post/read.rs
dullbananas 6497ec519e
Refactor LocalUser settings conditions in database views (#4746)
* Create viewer.rs

* Rename viewer.rs to viewer.rs

* Update viewer.rs

* Update post_view.rs

* Update distinguish.rs

* Update like.rs

* Update viewer.rs

* Update list_comment_likes.rs

* Update like.rs

* Update save.rs

* Update like.rs

* revert changes in api crate

* Update post_view.rs

* Update post_view.rs

* Update comment_view.rs

* Update post_view.rs

* Update community_view.rs

* Update comment_view.rs

* Update post_view.rs

* Update viewer.rs

* Update post_view.rs

* Update community_view.rs

* Update local_user_view.rs

* Update viewer.rs

* Update community_view.rs

* Update viewer.rs

* Update lib.rs

* Update comment_view.rs

* Update post_view.rs

* Update viewer.rs

* Update viewer.rs

* Update viewer.rs

* Update viewer.rs

* Update local_user_view.rs

* Update viewer.rs

* Update viewer.rs

* Update local_user_view.rs

* Update community_view.rs

* Update viewer.rs

* Update crates/db_schema/src/viewer.rs

Co-authored-by: SleeplessOne1917 <28871516+SleeplessOne1917@users.noreply.github.com>

* Update viewer.rs

* Update viewer.rs

* Update viewer.rs

* Update viewer.rs

* Update post_view.rs

* Update community_view.rs

* Update comment_view.rs

* Update viewer.rs

* Update post_view.rs

* Update save.rs

* Update resolve_object.rs

* Update viewer.rs

* Update save.rs

* Update resolve_object.rs

* Update comment_view.rs

* Update post_view.rs

* Update community_view.rs

* Update local_user_view.rs

* Update post_view.rs

* Update viewer.rs

* Update comment_view.rs

* Update post_view.rs

* Update community_view.rs

* Update viewer.rs

* Update viewer.rs

* Update viewer.rs

* Update viewer.rs

* Update viewer.rs

* Some additions to localuser DB view helpers. (#39)

* Some additions to localuser DB view helpers.

- Getting rid of generics.
- Passing in only LocalUser to views.

* Formatting fixes.

* Getting rid of unecessary as_refs

* Fixing clippy.

---------

Co-authored-by: SleeplessOne1917 <28871516+SleeplessOne1917@users.noreply.github.com>
Co-authored-by: Dessalines <dessalines@users.noreply.github.com>
Co-authored-by: Dessalines <tyhou13@gmx.com>
2024-06-14 21:51:24 -04:00

113 lines
3.1 KiB
Rust

use actix_web::web::{Data, Json, Query};
use lemmy_api_common::{
context::LemmyContext,
post::{GetPost, GetPostResponse},
utils::{check_private_instance, is_mod_or_admin_opt, mark_post_as_read, update_read_comments},
};
use lemmy_db_schema::{
source::{comment::Comment, post::Post},
traits::Crud,
};
use lemmy_db_views::{
post_view::PostQuery,
structs::{LocalUserView, PostView, SiteView},
};
use lemmy_db_views_actor::structs::{CommunityModeratorView, CommunityView};
use lemmy_utils::error::{LemmyErrorType, LemmyResult};
#[tracing::instrument(skip(context))]
pub async fn get_post(
data: Query<GetPost>,
context: Data<LemmyContext>,
local_user_view: Option<LocalUserView>,
) -> LemmyResult<Json<GetPostResponse>> {
let local_site = SiteView::read_local(&mut context.pool())
.await?
.ok_or(LemmyErrorType::LocalSiteNotSetup)?;
check_private_instance(&local_user_view, &local_site.local_site)?;
let person_id = local_user_view.as_ref().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?
.ok_or(LemmyErrorType::CouldntFindComment)?
.post_id
} else {
Err(LemmyErrorType::CouldntFindPost)?
};
// 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?
.ok_or(LemmyErrorType::CouldntFindPost)?
.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 post_view = PostView::read(&mut context.pool(), post_id, person_id, is_mod_or_admin)
.await?
.ok_or(LemmyErrorType::CouldntFindPost)?;
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?;
update_read_comments(
person_id,
post_id,
post_view.counts.comments,
&mut context.pool(),
)
.await?;
}
// Necessary for the sidebar subscribed
let community_view = CommunityView::read(
&mut context.pool(),
community_id,
person_id,
is_mod_or_admin,
)
.await?
.ok_or(LemmyErrorType::CouldntFindCommunity)?;
let moderators = CommunityModeratorView::for_community(&mut context.pool(), community_id).await?;
let local_user = local_user_view.as_ref().map(|u| &u.local_user);
// 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()),
local_user,
..Default::default()
}
.list(&local_site.site, &mut context.pool())
.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()
};
// Return the jwt
Ok(Json(GetPostResponse {
post_view,
community_view,
moderators,
cross_posts,
}))
}