mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-09-27 22:01:57 +00:00
9d26ac2c6f
* Fix listing type default value The listing type parameter is only meant for the frontpage, but is also applied inside of communities. The result is that this call returns nothing, because it defaults to ListingType::Local: https://fedibb.ml/api/v3/post/list?community_id=3 It needs to be called like this to get any posts: https://fedibb.ml/api/v3/post/list?community_id=3&type_=All This is clearly not expected behaviour, when a community is specified, the listing type should default to All. * fix clippy
221 lines
6.2 KiB
Rust
221 lines
6.2 KiB
Rust
use crate::{
|
|
api::PerformApub,
|
|
fetcher::resolve_actor_identifier,
|
|
objects::community::ApubCommunity,
|
|
};
|
|
use activitypub_federation::config::Data;
|
|
use lemmy_api_common::{
|
|
context::LemmyContext,
|
|
site::{Search, SearchResponse},
|
|
utils::{check_private_instance, get_local_user_view_from_jwt_opt, is_admin},
|
|
};
|
|
use lemmy_db_schema::{
|
|
source::{community::Community, local_site::LocalSite},
|
|
utils::post_to_comment_sort_type,
|
|
SearchType,
|
|
};
|
|
use lemmy_db_views::{comment_view::CommentQuery, post_view::PostQuery};
|
|
use lemmy_db_views_actor::{community_view::CommunityQuery, person_view::PersonQuery};
|
|
use lemmy_utils::{error::LemmyError, ConnectionId};
|
|
|
|
#[async_trait::async_trait]
|
|
impl PerformApub for Search {
|
|
type Response = SearchResponse;
|
|
|
|
#[tracing::instrument(skip(context, _websocket_id))]
|
|
async fn perform(
|
|
&self,
|
|
context: &Data<LemmyContext>,
|
|
_websocket_id: Option<ConnectionId>,
|
|
) -> Result<SearchResponse, LemmyError> {
|
|
let data: &Search = self;
|
|
|
|
let local_user_view =
|
|
get_local_user_view_from_jwt_opt(data.auth.as_ref(), context.pool(), context.secret())
|
|
.await?;
|
|
let local_site = LocalSite::read(context.pool()).await?;
|
|
|
|
check_private_instance(&local_user_view, &local_site)?;
|
|
|
|
let is_admin = local_user_view.as_ref().map(|luv| is_admin(luv).is_ok());
|
|
|
|
let mut posts = Vec::new();
|
|
let mut comments = Vec::new();
|
|
let mut communities = Vec::new();
|
|
let mut users = Vec::new();
|
|
|
|
// TODO no clean / non-nsfw searching rn
|
|
|
|
let q = data.q.clone();
|
|
let page = data.page;
|
|
let limit = data.limit;
|
|
let sort = data.sort;
|
|
let listing_type = data.listing_type;
|
|
let search_type = data.type_.unwrap_or(SearchType::All);
|
|
let community_id = if let Some(name) = &data.community_name {
|
|
resolve_actor_identifier::<ApubCommunity, Community>(name, context, &local_user_view, false)
|
|
.await
|
|
.ok()
|
|
.map(|c| c.id)
|
|
} else {
|
|
data.community_id
|
|
};
|
|
let creator_id = data.creator_id;
|
|
let local_user = local_user_view.map(|l| l.local_user);
|
|
match search_type {
|
|
SearchType::Posts => {
|
|
posts = PostQuery::builder()
|
|
.pool(context.pool())
|
|
.sort(sort)
|
|
.listing_type(listing_type)
|
|
.community_id(community_id)
|
|
.creator_id(creator_id)
|
|
.local_user(local_user.as_ref())
|
|
.search_term(Some(q))
|
|
.is_mod_or_admin(is_admin)
|
|
.page(page)
|
|
.limit(limit)
|
|
.build()
|
|
.list()
|
|
.await?;
|
|
}
|
|
SearchType::Comments => {
|
|
comments = CommentQuery::builder()
|
|
.pool(context.pool())
|
|
.sort(sort.map(post_to_comment_sort_type))
|
|
.listing_type(listing_type)
|
|
.search_term(Some(q))
|
|
.community_id(community_id)
|
|
.creator_id(creator_id)
|
|
.local_user(local_user.as_ref())
|
|
.page(page)
|
|
.limit(limit)
|
|
.build()
|
|
.list()
|
|
.await?;
|
|
}
|
|
SearchType::Communities => {
|
|
communities = CommunityQuery::builder()
|
|
.pool(context.pool())
|
|
.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)
|
|
.build()
|
|
.list()
|
|
.await?;
|
|
}
|
|
SearchType::Users => {
|
|
users = PersonQuery::builder()
|
|
.pool(context.pool())
|
|
.sort(sort)
|
|
.search_term(Some(q))
|
|
.page(page)
|
|
.limit(limit)
|
|
.build()
|
|
.list()
|
|
.await?;
|
|
}
|
|
SearchType::All => {
|
|
// If the community or creator is included, dont search communities or users
|
|
let community_or_creator_included =
|
|
data.community_id.is_some() || data.community_name.is_some() || data.creator_id.is_some();
|
|
|
|
let local_user_ = local_user.clone();
|
|
posts = PostQuery::builder()
|
|
.pool(context.pool())
|
|
.sort(sort)
|
|
.listing_type(listing_type)
|
|
.community_id(community_id)
|
|
.creator_id(creator_id)
|
|
.local_user(local_user_.as_ref())
|
|
.search_term(Some(q))
|
|
.is_mod_or_admin(is_admin)
|
|
.page(page)
|
|
.limit(limit)
|
|
.build()
|
|
.list()
|
|
.await?;
|
|
|
|
let q = data.q.clone();
|
|
|
|
let local_user_ = local_user.clone();
|
|
comments = CommentQuery::builder()
|
|
.pool(context.pool())
|
|
.sort(sort.map(post_to_comment_sort_type))
|
|
.listing_type(listing_type)
|
|
.search_term(Some(q))
|
|
.community_id(community_id)
|
|
.creator_id(creator_id)
|
|
.local_user(local_user_.as_ref())
|
|
.page(page)
|
|
.limit(limit)
|
|
.build()
|
|
.list()
|
|
.await?;
|
|
|
|
let q = data.q.clone();
|
|
|
|
communities = if community_or_creator_included {
|
|
vec![]
|
|
} else {
|
|
CommunityQuery::builder()
|
|
.pool(context.pool())
|
|
.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)
|
|
.build()
|
|
.list()
|
|
.await?
|
|
};
|
|
|
|
let q = data.q.clone();
|
|
|
|
users = if community_or_creator_included {
|
|
vec![]
|
|
} else {
|
|
PersonQuery::builder()
|
|
.pool(context.pool())
|
|
.sort(sort)
|
|
.search_term(Some(q))
|
|
.page(page)
|
|
.limit(limit)
|
|
.build()
|
|
.list()
|
|
.await?
|
|
};
|
|
}
|
|
SearchType::Url => {
|
|
posts = PostQuery::builder()
|
|
.pool(context.pool())
|
|
.sort(sort)
|
|
.listing_type(listing_type)
|
|
.community_id(community_id)
|
|
.creator_id(creator_id)
|
|
.url_search(Some(q))
|
|
.is_mod_or_admin(is_admin)
|
|
.page(page)
|
|
.limit(limit)
|
|
.build()
|
|
.list()
|
|
.await?;
|
|
}
|
|
};
|
|
|
|
// Return the jwt
|
|
Ok(SearchResponse {
|
|
type_: search_type.to_string(),
|
|
comments,
|
|
posts,
|
|
communities,
|
|
users,
|
|
})
|
|
}
|
|
}
|