lemmynsfw-changes
Felix Ableitner 2024-01-23 13:02:11 +01:00
parent d18ac067c5
commit c537cf298a
14 changed files with 168 additions and 174 deletions

2
Cargo.lock generated
View File

@ -2708,6 +2708,7 @@ dependencies = [
"tokio",
"tracing",
"ts-rs",
"typed-builder",
]
[[package]]
@ -2726,6 +2727,7 @@ dependencies = [
"strum_macros",
"tokio",
"ts-rs",
"typed-builder",
]
[[package]]

View File

@ -31,7 +31,8 @@ pub async fn like_post(
let post_id = data.post_id;
let post = Post::read(&mut context.pool(), post_id).await?;
// TODO: need to read community both here are for check_community_user_action()
// TODO: need to read community both here are for check_community_user_action(), would be good to
// read it only once
let community = Community::read(&mut context.pool(), post.community_id).await?;
check_vote_permission(
data.score,

View File

@ -840,7 +840,6 @@ pub async fn check_vote_permission(
if community.only_followers_can_vote
&& !CommunityFollower::is_follower(&mut context.pool(), person.id, community.id).await?
{
// TODO: lemmynsfw code checks that follow was at least 10 minutes ago
Err(LemmyErrorType::DownvotesAreDisabled)?
}
Ok(())

View File

@ -29,18 +29,18 @@ pub async fn list_communities(
let page = data.page;
let limit = data.limit;
let local_user = local_user_view.map(|l| l.local_user);
let communities = CommunityQuery {
listing_type,
show_nsfw,
sort,
local_user: local_user.as_ref(),
page,
limit,
is_mod_or_admin: is_admin,
..Default::default()
}
.list(&mut context.pool())
.await?;
let communities = CommunityQuery::builder()
.local_site(local_site)
.listing_type(listing_type)
.show_nsfw(show_nsfw)
.sort(sort)
.local_user(local_user.as_ref())
.page(page)
.limit(limit)
.is_mod_or_admin(is_admin)
.build()
.list(&mut context.pool())
.await?;
// Return the jwt
Ok(Json(ListCommunitiesResponse { communities }))

View File

@ -89,12 +89,12 @@ pub async fn get_post(
// 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 mut x_posts = PostQuery::builder()
.local_site(local_site)
.url_search(Some(url.inner().as_str().into()))
.build()
.list(&mut context.pool())
.await?;
// Don't return this post as one of the cross_posts
x_posts.retain(|x| x.post.id != post_id);

View File

@ -67,11 +67,9 @@ async fn vote_comment(
person_id: actor.id,
score: vote_type.into(),
};
let person_id = actor.id;
// TODO: inefficient
let post = Post::read(&mut context.pool(), comment.post_id).await?;
check_vote_permission(Some(vote_type), &actor, post.community_id, context).await?;
CommentLike::remove(&mut context.pool(), person_id, comment_id).await?;
CommentLike::remove(&mut context.pool(), actor.id, comment_id).await?;
CommentLike::like(&mut context.pool(), &like_form).await?;
Ok(())
}
@ -102,12 +100,9 @@ async fn undo_vote_comment(
comment: &ApubComment,
context: &Data<LemmyContext>,
) -> Result<(), LemmyError> {
let comment_id = comment.id;
let person_id = actor.id;
// TODO: inefficient
let post = Post::read(&mut context.pool(), comment.post_id).await?;
check_vote_permission(None, &actor, post.community_id, context).await?;
CommentLike::remove(&mut context.pool(), person_id, comment_id).await?;
CommentLike::remove(&mut context.pool(), actor.id, comment.id).await?;
Ok(())
}
@ -117,10 +112,8 @@ async fn undo_vote_post(
post: &ApubPost,
context: &Data<LemmyContext>,
) -> Result<(), LemmyError> {
let post_id = post.id;
let person_id = actor.id;
check_vote_permission(None, &actor, post.community_id, context).await?;
PostLike::remove(&mut context.pool(), person_id, post_id).await?;
PostLike::remove(&mut context.pool(), actor.id, post.id).await?;
Ok(())
}

View File

@ -57,22 +57,22 @@ pub async fn list_posts(
None
};
let posts = PostQuery {
local_user: local_user_view.as_ref(),
listing_type,
sort,
community_id,
saved_only,
liked_only,
disliked_only,
page,
page_after,
limit,
..Default::default()
}
.list(&mut context.pool())
.await
.with_lemmy_type(LemmyErrorType::CouldntGetPosts)?;
let posts = PostQuery::builder()
.local_site(local_site)
.local_user(local_user_view.as_ref())
.listing_type(listing_type)
.sort(sort)
.community_id(community_id)
.saved_only(saved_only)
.liked_only(liked_only)
.disliked_only(disliked_only)
.page(page)
.page_after(page_after)
.limit(limit)
.build()
.list(&mut context.pool())
.await
.with_lemmy_type(LemmyErrorType::CouldntGetPosts)?;
// if this page wasn't empty, then there is a next page after the last post on this page
let next_page = posts.last().map(PaginationCursor::after_post);

View File

@ -60,18 +60,18 @@ pub async fn read_person(
None
};
let posts = PostQuery {
sort,
saved_only,
local_user: local_user_view.as_ref(),
community_id,
page,
limit,
creator_id,
..Default::default()
}
.list(&mut context.pool())
.await?;
let posts = PostQuery::builder()
.local_site(local_site)
.local_user(local_user_view.as_ref())
.sort(sort)
.community_id(community_id)
.saved_only(saved_only)
.page(page)
.limit(limit)
.creator_id(creator_id)
.build()
.list(&mut context.pool())
.await?;
let comments = CommentQuery {
local_user: local_user_view.as_ref(),

View File

@ -56,19 +56,19 @@ pub async fn search(
let local_user = local_user_view.as_ref().map(|l| l.local_user.clone());
match search_type {
SearchType::Posts => {
posts = PostQuery {
sort: (sort),
listing_type: (listing_type),
community_id: (community_id),
creator_id: (creator_id),
local_user: (local_user_view.as_ref()),
search_term: (Some(q)),
page: (page),
limit: (limit),
..Default::default()
}
.list(&mut context.pool())
.await?;
PostQuery::builder()
.local_site(local_site)
.local_user(local_user_view.as_ref())
.sort(sort)
.community_id(community_id)
.creator_id(creator_id)
.listing_type(listing_type)
.search_term(Some(q))
.page(page)
.limit(limit)
.build()
.list(&mut context.pool())
.await?;
}
SearchType::Comments => {
comments = CommentQuery {
@ -86,18 +86,18 @@ pub async fn search(
.await?;
}
SearchType::Communities => {
communities = CommunityQuery {
sort: (sort),
listing_type: (listing_type),
search_term: (Some(q)),
local_user: (local_user.as_ref()),
is_mod_or_admin: (is_admin),
page: (page),
limit: (limit),
..Default::default()
}
.list(&mut context.pool())
.await?;
communities = CommunityQuery::builder()
.local_site(local_site)
.listing_type(listing_type)
.sort(sort)
.local_user(local_user.as_ref())
.page(page)
.limit(limit)
.search_term(Some(q))
.is_mod_or_admin(is_admin)
.build()
.list(&mut context.pool())
.await?;
}
SearchType::Users => {
users = PersonQuery {
@ -116,19 +116,19 @@ pub async fn search(
let q = data.q.clone();
posts = PostQuery {
sort: (sort),
listing_type: (listing_type),
community_id: (community_id),
creator_id: (creator_id),
local_user: (local_user_view.as_ref()),
search_term: (Some(q)),
page: (page),
limit: (limit),
..Default::default()
}
.list(&mut context.pool())
.await?;
posts = PostQuery::builder()
.local_site(local_site.clone())
.local_user(local_user_view.as_ref())
.sort(sort)
.community_id(community_id)
.creator_id(creator_id)
.listing_type(listing_type)
.search_term(Some(q))
.page(page)
.limit(limit)
.build()
.list(&mut context.pool())
.await?;
let q = data.q.clone();
@ -151,18 +151,18 @@ pub async fn search(
communities = if community_or_creator_included {
vec![]
} else {
CommunityQuery {
sort: (sort),
listing_type: (listing_type),
search_term: (Some(q)),
local_user: (local_user.as_ref()),
is_mod_or_admin: (is_admin),
page: (page),
limit: (limit),
..Default::default()
}
.list(&mut context.pool())
.await?
CommunityQuery::builder()
.local_site(local_site)
.listing_type(listing_type)
.sort(sort)
.local_user(local_user.as_ref())
.page(page)
.limit(limit)
.search_term(Some(q))
.is_mod_or_admin(is_admin)
.build()
.list(&mut context.pool())
.await?
};
let q = data.q.clone();
@ -181,18 +181,19 @@ pub async fn search(
};
}
SearchType::Url => {
posts = PostQuery {
sort: (sort),
listing_type: (listing_type),
community_id: (community_id),
creator_id: (creator_id),
url_search: (Some(q)),
page: (page),
limit: (limit),
..Default::default()
}
.list(&mut context.pool())
.await?;
posts = PostQuery::builder()
.local_site(local_site)
.local_user(local_user_view.as_ref())
.sort(sort)
.community_id(community_id)
.creator_id(creator_id)
.listing_type(listing_type)
.search_term(Some(q))
.page(page)
.limit(limit)
.build()
.list(&mut context.pool())
.await?;
}
};

View File

@ -37,6 +37,7 @@ serde_with = { workspace = true }
tracing = { workspace = true, optional = true }
ts-rs = { workspace = true, optional = true }
actix-web = { workspace = true, optional = true }
typed-builder = { workspace = true }
[dev-dependencies]
serial_test = { workspace = true }

View File

@ -26,7 +26,6 @@ use lemmy_db_schema::{
community_moderator,
community_person_ban,
instance_block,
local_site::dsl::local_site,
local_user,
local_user_language,
person,
@ -55,6 +54,7 @@ use lemmy_db_schema::{
SortType,
};
use tracing::debug;
use typed_builder::TypedBuilder;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
enum Ord {
@ -386,12 +386,7 @@ fn queries<'a>() -> Queries<
}
// If there is a content warning, show nsfw content by default.
// TODO: inefficient
let has_content_warning = local_site
.first::<LocalSite>(&mut conn)
.await?
.content_warning
.is_some();
let has_content_warning = options.local_site.content_warning.is_some();
if !options
.local_user
.map(|l| l.local_user.show_nsfw)
@ -616,8 +611,11 @@ impl PaginationCursor {
#[derive(Clone)]
pub struct PaginationCursorData(PostAggregates);
#[derive(Default, Clone)]
#[derive(Clone, TypedBuilder)]
#[builder(field_defaults(default))]
pub struct PostQuery<'a> {
#[builder(!default)]
pub local_site: LocalSite,
pub listing_type: Option<ListingType>,
pub sort: Option<SortType>,
pub creator_id: Option<PersonId>,

View File

@ -34,6 +34,7 @@ ts-rs = { workspace = true, optional = true }
chrono.workspace = true
strum = { workspace = true }
strum_macros = { workspace = true }
typed-builder = { workspace = true }
[dev-dependencies]
serial_test = { workspace = true }

View File

@ -18,7 +18,6 @@ use lemmy_db_schema::{
community_block,
community_follower,
instance_block,
local_site::dsl::local_site,
local_user,
},
source::{community::CommunityFollower, local_site::LocalSite, local_user::LocalUser},
@ -26,6 +25,7 @@ use lemmy_db_schema::{
ListingType,
SortType,
};
use typed_builder::TypedBuilder;
fn queries<'a>() -> Queries<
impl ReadFn<'a, CommunityView, (CommunityId, Option<PersonId>, bool)>,
@ -155,12 +155,7 @@ fn queries<'a>() -> Queries<
} else {
// No person in request, only show nsfw communities if show_nsfw is passed into request or if
// site has content warning.
// TODO: inefficient
let has_content_warning = local_site
.first::<LocalSite>(&mut conn)
.await?
.content_warning
.is_some();
let has_content_warning = options.local_site.content_warning.is_some();
if !options.show_nsfw && !has_content_warning {
query = query.filter(community::nsfw.eq(false));
}
@ -220,8 +215,11 @@ impl CommunityView {
}
}
#[derive(Default)]
#[derive(TypedBuilder)]
#[builder(field_defaults(default))]
pub struct CommunityQuery<'a> {
#[builder(!default)]
pub local_site: LocalSite,
pub listing_type: Option<ListingType>,
pub sort: Option<SortType>,
pub local_user: Option<&'a LocalUser>,

View File

@ -128,15 +128,15 @@ async fn get_feed_data(
check_private_instance(&None, &site_view.local_site)?;
let posts = PostQuery {
listing_type: (Some(listing_type)),
sort: (Some(sort_type)),
limit: (Some(limit)),
page: (Some(page)),
..Default::default()
}
.list(&mut context.pool())
.await?;
let posts = PostQuery::builder()
.local_site(site_view.local_site)
.listing_type(Some(listing_type))
.sort(Some(sort_type))
.limit(Some(limit))
.page(Some(page))
.build()
.list(&mut context.pool())
.await?;
let items = create_post_items(posts, &context.settings().get_protocol_and_hostname())?;
@ -234,16 +234,16 @@ async fn get_feed_user(
check_private_instance(&None, &site_view.local_site)?;
let posts = PostQuery {
listing_type: (Some(ListingType::All)),
sort: (Some(*sort_type)),
creator_id: (Some(person.id)),
limit: (Some(*limit)),
page: (Some(*page)),
..Default::default()
}
.list(&mut context.pool())
.await?;
let posts = PostQuery::builder()
.local_site(site_view.local_site)
.listing_type(Some(ListingType::All))
.creator_id(Some(person.id))
.sort(Some(*sort_type))
.limit(Some(*limit))
.page(Some(*page))
.build()
.list(&mut context.pool())
.await?;
let items = create_post_items(posts, &context.settings().get_protocol_and_hostname())?;
@ -271,15 +271,15 @@ async fn get_feed_community(
check_private_instance(&None, &site_view.local_site)?;
let posts = PostQuery {
sort: (Some(*sort_type)),
community_id: (Some(community.id)),
limit: (Some(*limit)),
page: (Some(*page)),
..Default::default()
}
.list(&mut context.pool())
.await?;
let posts = PostQuery::builder()
.local_site(site_view.local_site)
.community_id(Some(community.id))
.sort(Some(*sort_type))
.limit(Some(*limit))
.page(Some(*page))
.build()
.list(&mut context.pool())
.await?;
let items = create_post_items(posts, &context.settings().get_protocol_and_hostname())?;
@ -311,16 +311,16 @@ async fn get_feed_front(
check_private_instance(&Some(local_user.clone()), &site_view.local_site)?;
let posts = PostQuery {
listing_type: (Some(ListingType::Subscribed)),
local_user: (Some(&local_user)),
sort: (Some(*sort_type)),
limit: (Some(*limit)),
page: (Some(*page)),
..Default::default()
}
.list(&mut context.pool())
.await?;
let posts = PostQuery::builder()
.local_site(site_view.local_site)
.listing_type(Some(ListingType::Subscribed))
.local_user(Some(&local_user))
.sort(Some(*sort_type))
.limit(Some(*limit))
.page(Some(*page))
.build()
.list(&mut context.pool())
.await?;
let protocol_and_hostname = context.settings().get_protocol_and_hostname();
let items = create_post_items(posts, &protocol_and_hostname)?;