@ -21,46 +21,68 @@ use lemmy_utils::{
error ::{ LemmyError , LemmyErrorExt , LemmyErrorType } ,
version ,
} ;
use moka ::future ::Cache ;
use once_cell ::sync ::Lazy ;
use std ::time ::Duration ;
#[ tracing::instrument(skip(context)) ]
pub async fn get_site (
local_user_view : Option < LocalUserView > ,
context : Data < LemmyContext > ,
) -> Result < Json < GetSiteResponse > , LemmyError > {
let site_view = SiteView ::read_local ( & mut context . pool ( ) ) . await ? ;
static CACHE : Lazy < Cache < ( ) , GetSiteResponse > > = Lazy ::new ( | | {
Cache ::builder ( )
. max_capacity ( 1 )
. time_to_live ( Duration ::from_secs ( 1 ) )
. build ( )
} ) ;
let admins = PersonView ::admins ( & mut context . pool ( ) ) . await ? ;
// This data is independent from the user account so we can cache it across requests
let mut site_response = CACHE
. try_get_with ::< _ , LemmyError > ( ( ) , async {
let site_view = SiteView ::read_local ( & mut context . pool ( ) ) . await ? ;
let admins = PersonView ::admins ( & mut context . pool ( ) ) . await ? ;
let all_languages = Language ::read_all ( & mut context . pool ( ) ) . await ? ;
let discussion_languages = SiteLanguage ::read_local_raw ( & mut context . pool ( ) ) . await ? ;
let taglines = Tagline ::get_all ( & mut context . pool ( ) , site_view . local_site . id ) . await ? ;
let custom_emojis =
CustomEmojiView ::get_all ( & mut context . pool ( ) , site_view . local_site . id ) . await ? ;
Ok ( GetSiteResponse {
site_view ,
admins ,
version : version ::VERSION . to_string ( ) ,
my_user : None ,
all_languages ,
discussion_languages ,
taglines ,
custom_emojis ,
} )
} )
. await
. map_err ( | e | anyhow ::anyhow ! ( "Failed to construct site response: {e}" ) ) ? ;
// Build the local user
let my_user = if let Some ( local_user_view ) = local_user_view {
// Build the local user with parallel queries and add it to site response
site_response . my_user = if let Some ( local_user_view ) = local_user_view {
let person_id = local_user_view . person . id ;
let local_user_id = local_user_view . local_user . id ;
let pool = & mut context . pool ( ) ;
let follows = CommunityFollowerView ::for_person ( & mut context . pool ( ) , person_id )
. await
. with_lemmy_type ( LemmyErrorType ::SystemErrLogin ) ? ;
let person_id = local_user_view . person . id ;
let community_blocks = CommunityBlockView ::for_person ( & mut context . pool ( ) , person_id )
. await
. with_lemmy_type ( LemmyErrorType ::SystemErrLogin ) ? ;
let instance_blocks = InstanceBlockView ::for_person ( & mut context . pool ( ) , person_id )
. await
. with_lemmy_type ( LemmyErrorType ::SystemErrLogin ) ? ;
let person_id = local_user_view . person . id ;
let person_blocks = PersonBlockView ::for_person ( & mut context . pool ( ) , person_id )
. await
. with_lemmy_type ( LemmyErrorType ::SystemErrLogin ) ? ;
let moderates = CommunityModeratorView ::for_person ( & mut context . pool ( ) , person_id )
. await
. with_lemmy_type ( LemmyErrorType ::SystemErrLogin ) ? ;
let discussion_languages = LocalUserLanguage ::read ( & mut context . pool ( ) , local_user_id )
. await
. with_lemmy_type ( LemmyErrorType ::SystemErrLogin ) ? ;
let (
follows ,
community_blocks ,
instance_blocks ,
person_blocks ,
moderates ,
discussion_languages ,
) = lemmy_db_schema ::try_join_with_pool ! ( pool = > (
| pool | CommunityFollowerView ::for_person ( pool , person_id ) ,
| pool | CommunityBlockView ::for_person ( pool , person_id ) ,
| pool | InstanceBlockView ::for_person ( pool , person_id ) ,
| pool | PersonBlockView ::for_person ( pool , person_id ) ,
| pool | CommunityModeratorView ::for_person ( pool , person_id ) ,
| pool | LocalUserLanguage ::read ( pool , local_user_id )
) )
. with_lemmy_type ( LemmyErrorType ::SystemErrLogin ) ? ;
Some ( MyUserInfo {
local_user_view ,
@ -75,20 +97,5 @@ pub async fn get_site(
None
} ;
let all_languages = Language ::read_all ( & mut context . pool ( ) ) . await ? ;
let discussion_languages = SiteLanguage ::read_local_raw ( & mut context . pool ( ) ) . await ? ;
let taglines = Tagline ::get_all ( & mut context . pool ( ) , site_view . local_site . id ) . await ? ;
let custom_emojis =
CustomEmojiView ::get_all ( & mut context . pool ( ) , site_view . local_site . id ) . await ? ;
Ok ( Json ( GetSiteResponse {
site_view ,
admins ,
version : version ::VERSION . to_string ( ) ,
my_user ,
all_languages ,
discussion_languages ,
taglines ,
custom_emojis ,
} ) )
Ok ( Json ( site_response ) )
}