Skip to content

Commit

Permalink
Adding a get_random_community endpoint. (#5042)
Browse files Browse the repository at this point in the history
* Adding a get_random_community endpoint.

- Fixes #4698

* Fixing issue from main.

* Adding ListingType to the query.

* More concise query filter.
  • Loading branch information
dessalines authored Oct 2, 2024
1 parent 483bdd5 commit 432d46c
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 11 deletions.
1 change: 1 addition & 0 deletions crates/api/src/community/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ pub mod ban;
pub mod block;
pub mod follow;
pub mod hide;
pub mod random;
pub mod transfer;
55 changes: 55 additions & 0 deletions crates/api/src/community/random.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
use activitypub_federation::config::Data;
use actix_web::web::{Json, Query};
use lemmy_api_common::{
community::{CommunityResponse, GetRandomCommunity},
context::LemmyContext,
utils::{check_private_instance, is_mod_or_admin_opt},
};
use lemmy_db_schema::source::{
actor_language::CommunityLanguage,
community::Community,
local_site::LocalSite,
};
use lemmy_db_views::structs::LocalUserView;
use lemmy_db_views_actor::structs::CommunityView;
use lemmy_utils::error::LemmyResult;

#[tracing::instrument(skip(context))]
pub async fn get_random_community(
data: Query<GetRandomCommunity>,
context: Data<LemmyContext>,
local_user_view: Option<LocalUserView>,
) -> LemmyResult<Json<CommunityResponse>> {
let local_site = LocalSite::read(&mut context.pool()).await?;

check_private_instance(&local_user_view, &local_site)?;

let local_user = local_user_view.as_ref().map(|u| &u.local_user);

let random_community_id =
Community::get_random_community_id(&mut context.pool(), &data.type_).await?;

let is_mod_or_admin = is_mod_or_admin_opt(
&mut context.pool(),
local_user_view.as_ref(),
Some(random_community_id),
)
.await
.is_ok();

let community_view = CommunityView::read(
&mut context.pool(),
random_community_id,
local_user,
is_mod_or_admin,
)
.await?;

let discussion_languages =
CommunityLanguage::read(&mut context.pool(), random_community_id).await?;

Ok(Json(CommunityResponse {
community_view,
discussion_languages,
}))
}
2 changes: 1 addition & 1 deletion crates/api/src/site/leave_admin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ pub async fn leave_admin(
let discussion_languages = SiteLanguage::read_local_raw(&mut context.pool()).await?;
let oauth_providers = OAuthProvider::get_all_public(&mut context.pool()).await?;
let blocked_urls = LocalSiteUrlBlocklist::get_all(&mut context.pool()).await?;
let tagline = Tagline::get_random(&mut context.pool()).await?;
let tagline = Tagline::get_random(&mut context.pool()).await.ok();

Ok(Json(GetSiteResponse {
site_view,
Expand Down
9 changes: 9 additions & 0 deletions crates/api_common/src/community.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,3 +225,12 @@ pub struct TransferCommunity {
pub community_id: CommunityId,
pub person_id: PersonId,
}

#[skip_serializing_none]
#[derive(Debug, Serialize, Deserialize, Clone, Default, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "full", derive(TS))]
#[cfg_attr(feature = "full", ts(export))]
/// Fetches a random community
pub struct GetRandomCommunity {
pub type_: Option<ListingType>,
}
2 changes: 1 addition & 1 deletion crates/api_crud/src/site/read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ pub async fn get_site(
let all_languages = Language::read_all(&mut context.pool()).await?;
let discussion_languages = SiteLanguage::read_local_raw(&mut context.pool()).await?;
let blocked_urls = LocalSiteUrlBlocklist::get_all(&mut context.pool()).await?;
let tagline = Tagline::get_random(&mut context.pool()).await?;
let tagline = Tagline::get_random(&mut context.pool()).await.ok();
let admin_oauth_providers = OAuthProvider::get_all(&mut context.pool()).await?;
let oauth_providers =
OAuthProvider::convert_providers_to_public(admin_oauth_providers.clone());
Expand Down
27 changes: 26 additions & 1 deletion crates/db_schema/src/impls/community.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,13 @@ use crate::{
get_conn,
DbPool,
},
ListingType,
SubscribedType,
};
use chrono::{DateTime, Utc};
use diesel::{
deserialize,
dsl::{self, exists, insert_into},
dsl::{self, exists, insert_into, not},
pg::Pg,
result::Error,
select,
Expand Down Expand Up @@ -193,6 +194,30 @@ impl Community {
.await?;
Ok(())
}

pub async fn get_random_community_id(
pool: &mut DbPool<'_>,
type_: &Option<ListingType>,
) -> Result<CommunityId, Error> {
let conn = &mut get_conn(pool).await?;
sql_function!(fn random() -> Text);

let mut query = community::table
.filter(not(community::deleted))
.filter(not(community::removed))
.into_boxed();

if let Some(ListingType::Local) = type_ {
query = query.filter(community::local);
}

query
.select(community::id)
.order(random())
.limit(1)
.first::<CommunityId>(conn)
.await
}
}

impl CommunityModerator {
Expand Down
11 changes: 3 additions & 8 deletions crates/db_schema/src/impls/tagline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{
traits::Crud,
utils::{get_conn, limit_and_offset, DbPool},
};
use diesel::{insert_into, result::Error, ExpressionMethods, OptionalExtension, QueryDsl};
use diesel::{insert_into, result::Error, ExpressionMethods, QueryDsl};
use diesel_async::RunQueryDsl;

#[async_trait]
Expand Down Expand Up @@ -51,14 +51,9 @@ impl Tagline {
.await
}

pub async fn get_random(pool: &mut DbPool<'_>) -> Result<Option<Self>, Error> {
pub async fn get_random(pool: &mut DbPool<'_>) -> Result<Self, Error> {
let conn = &mut get_conn(pool).await?;
sql_function!(fn random() -> Text);
tagline
.order(random())
.limit(1)
.first::<Self>(conn)
.await
.optional()
tagline.order(random()).limit(1).first::<Self>(conn).await
}
}
2 changes: 2 additions & 0 deletions src/api_routes_http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use lemmy_api::{
block::block_community,
follow::follow_community,
hide::hide_community,
random::get_random_community,
transfer::transfer_community,
},
local_user::{
Expand Down Expand Up @@ -193,6 +194,7 @@ pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimitCell) {
.wrap(rate_limit.message())
.route("", web::get().to(get_community))
.route("", web::put().to(update_community))
.route("/random", web::get().to(get_random_community))
.route("/hide", web::put().to(hide_community))
.route("/list", web::get().to(list_communities))
.route("/follow", web::post().to(follow_community))
Expand Down

0 comments on commit 432d46c

Please sign in to comment.