Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding a get_random_community endpoint. #5042

Merged
merged 8 commits into from
Oct 2, 2024
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