Merge remote-tracking branch 'origin/main' into change_vote_display_mode_defaults

This commit is contained in:
Dessalines 2024-04-09 19:34:24 -04:00
commit 89d5627963
16 changed files with 89 additions and 60 deletions

View File

@ -19,7 +19,6 @@ use lemmy_db_schema::{
comment_reply::{CommentReply, CommentReplyInsertForm}, comment_reply::{CommentReply, CommentReplyInsertForm},
person::Person, person::Person,
person_mention::{PersonMention, PersonMentionInsertForm}, person_mention::{PersonMention, PersonMentionInsertForm},
post::Post,
}, },
traits::Crud, traits::Crud,
}; };
@ -91,16 +90,19 @@ pub async fn build_post_response(
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
pub async fn send_local_notifs( pub async fn send_local_notifs(
mentions: Vec<MentionData>, mentions: Vec<MentionData>,
comment: &Comment, comment_id: CommentId,
person: &Person, person: &Person,
post: &Post,
do_send_email: bool, do_send_email: bool,
context: &LemmyContext, context: &LemmyContext,
) -> Result<Vec<LocalUserId>, LemmyError> { ) -> Result<Vec<LocalUserId>, LemmyError> {
let mut recipient_ids = Vec::new(); let mut recipient_ids = Vec::new();
let inbox_link = format!("{}/inbox", context.settings().get_protocol_and_hostname()); let inbox_link = format!("{}/inbox", context.settings().get_protocol_and_hostname());
let community_id = post.community_id; // Read the comment view to get extra info
let comment_view = CommentView::read(&mut context.pool(), comment_id, None).await?;
let comment = comment_view.comment;
let post = comment_view.post;
let community = comment_view.community;
// Send the local mentions // Send the local mentions
for mention in mentions for mention in mentions
@ -117,7 +119,7 @@ pub async fn send_local_notifs(
let user_mention_form = PersonMentionInsertForm { let user_mention_form = PersonMentionInsertForm {
recipient_id: mention_user_view.person.id, recipient_id: mention_user_view.person.id,
comment_id: comment.id, comment_id,
read: None, read: None,
}; };
@ -152,8 +154,9 @@ pub async fn send_local_notifs(
let check_blocks = check_person_instance_community_block( let check_blocks = check_person_instance_community_block(
person.id, person.id,
parent_creator_id, parent_creator_id,
person.instance_id, // Only block from the community's instance_id
community_id, community.instance_id,
community.id,
&mut context.pool(), &mut context.pool(),
) )
.await .await
@ -194,11 +197,13 @@ pub async fn send_local_notifs(
} }
} }
} else { } else {
// Use the post creator to check blocks
let check_blocks = check_person_instance_community_block( let check_blocks = check_person_instance_community_block(
person.id, person.id,
post.creator_id, post.creator_id,
person.instance_id, // Only block from the community's instance_id
community_id, community.instance_id,
community.id,
&mut context.pool(), &mut context.pool(),
) )
.await .await

View File

@ -27,7 +27,7 @@ pub extern crate lemmy_utils;
pub use lemmy_utils::LemmyErrorType; pub use lemmy_utils::LemmyErrorType;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::time::Duration; use std::{cmp::min, time::Duration};
#[derive(Debug, Serialize, Deserialize, Clone)] #[derive(Debug, Serialize, Deserialize, Clone)]
#[cfg_attr(feature = "full", derive(ts_rs::TS))] #[cfg_attr(feature = "full", derive(ts_rs::TS))]
@ -43,7 +43,39 @@ impl Default for SuccessResponse {
} }
} }
/// how long to sleep based on how many retries have already happened // TODO: use from_days once stabilized
// https://github.com/rust-lang/rust/issues/120301
const DAY: Duration = Duration::from_secs(24 * 60 * 60);
/// Calculate how long to sleep until next federation send based on how many
/// retries have already happened. Uses exponential backoff with maximum of one day. The first
/// error is ignored.
pub fn federate_retry_sleep_duration(retry_count: i32) -> Duration { pub fn federate_retry_sleep_duration(retry_count: i32) -> Duration {
Duration::from_secs_f64(2.0_f64.powf(f64::from(retry_count))) debug_assert!(retry_count != 0);
if retry_count == 1 {
return Duration::from_secs(0);
}
let retry_count = retry_count - 1;
let pow = 1.25_f64.powf(retry_count.into());
let pow = Duration::try_from_secs_f64(pow).unwrap_or(DAY);
min(DAY, pow)
}
#[cfg(test)]
pub(crate) mod tests {
use super::*;
#[test]
fn test_federate_retry_sleep_duration() {
assert_eq!(Duration::from_secs(0), federate_retry_sleep_duration(1));
assert_eq!(
Duration::new(1, 250000000),
federate_retry_sleep_duration(2)
);
assert_eq!(
Duration::new(2, 441406250),
federate_retry_sleep_duration(5)
);
assert_eq!(DAY, federate_retry_sleep_duration(100));
}
} }

View File

@ -42,7 +42,7 @@ use lemmy_utils::{
markdown::{markdown_check_for_blocked_urls, markdown_rewrite_image_links}, markdown::{markdown_check_for_blocked_urls, markdown_rewrite_image_links},
slurs::{build_slur_regex, remove_slurs}, slurs::{build_slur_regex, remove_slurs},
}, },
CACHE_DURATION_SHORT, CACHE_DURATION_FEDERATION,
}; };
use moka::future::Cache; use moka::future::Cache;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
@ -295,12 +295,12 @@ async fn check_instance_block(
pub async fn check_person_instance_community_block( pub async fn check_person_instance_community_block(
my_id: PersonId, my_id: PersonId,
potential_blocker_id: PersonId, potential_blocker_id: PersonId,
instance_id: InstanceId, community_instance_id: InstanceId,
community_id: CommunityId, community_id: CommunityId,
pool: &mut DbPool<'_>, pool: &mut DbPool<'_>,
) -> Result<(), LemmyError> { ) -> Result<(), LemmyError> {
check_person_block(my_id, potential_blocker_id, pool).await?; check_person_block(my_id, potential_blocker_id, pool).await?;
check_instance_block(instance_id, potential_blocker_id, pool).await?; check_instance_block(community_instance_id, potential_blocker_id, pool).await?;
check_community_block(community_id, potential_blocker_id, pool).await?; check_community_block(community_id, potential_blocker_id, pool).await?;
Ok(()) Ok(())
} }
@ -524,7 +524,7 @@ pub async fn get_url_blocklist(context: &LemmyContext) -> LemmyResult<RegexSet>
static URL_BLOCKLIST: Lazy<Cache<(), RegexSet>> = Lazy::new(|| { static URL_BLOCKLIST: Lazy<Cache<(), RegexSet>> = Lazy::new(|| {
Cache::builder() Cache::builder()
.max_capacity(1) .max_capacity(1)
.time_to_live(CACHE_DURATION_SHORT) .time_to_live(CACHE_DURATION_FEDERATION)
.build() .build()
}); });

View File

@ -138,9 +138,8 @@ pub async fn create_comment(
let mentions = scrape_text_for_mentions(&content); let mentions = scrape_text_for_mentions(&content);
let recipient_ids = send_local_notifs( let recipient_ids = send_local_notifs(
mentions, mentions,
&updated_comment, inserted_comment_id,
&local_user_view.person, &local_user_view.person,
&post,
true, true,
&context, &context,
) )

View File

@ -8,10 +8,7 @@ use lemmy_api_common::{
utils::check_community_user_action, utils::check_community_user_action,
}; };
use lemmy_db_schema::{ use lemmy_db_schema::{
source::{ source::comment::{Comment, CommentUpdateForm},
comment::{Comment, CommentUpdateForm},
post::Post,
},
traits::Crud, traits::Crud,
}; };
use lemmy_db_views::structs::{CommentView, LocalUserView}; use lemmy_db_views::structs::{CommentView, LocalUserView};
@ -56,17 +53,8 @@ pub async fn delete_comment(
.await .await
.with_lemmy_type(LemmyErrorType::CouldntUpdateComment)?; .with_lemmy_type(LemmyErrorType::CouldntUpdateComment)?;
let post_id = updated_comment.post_id; let recipient_ids =
let post = Post::read(&mut context.pool(), post_id).await?; send_local_notifs(vec![], comment_id, &local_user_view.person, false, &context).await?;
let recipient_ids = send_local_notifs(
vec![],
&updated_comment,
&local_user_view.person,
&post,
false,
&context,
)
.await?;
let updated_comment_id = updated_comment.id; let updated_comment_id = updated_comment.id;
ActivityChannel::submit_activity( ActivityChannel::submit_activity(

View File

@ -12,7 +12,6 @@ use lemmy_db_schema::{
comment::{Comment, CommentUpdateForm}, comment::{Comment, CommentUpdateForm},
comment_report::CommentReport, comment_report::CommentReport,
moderator::{ModRemoveComment, ModRemoveCommentForm}, moderator::{ModRemoveComment, ModRemoveCommentForm},
post::Post,
}, },
traits::{Crud, Reportable}, traits::{Crud, Reportable},
}; };
@ -61,13 +60,10 @@ pub async fn remove_comment(
}; };
ModRemoveComment::create(&mut context.pool(), &form).await?; ModRemoveComment::create(&mut context.pool(), &form).await?;
let post_id = updated_comment.post_id;
let post = Post::read(&mut context.pool(), post_id).await?;
let recipient_ids = send_local_notifs( let recipient_ids = send_local_notifs(
vec![], vec![],
&updated_comment, comment_id,
&local_user_view.person.clone(), &local_user_view.person.clone(),
&post,
false, false,
&context, &context,
) )

View File

@ -79,9 +79,8 @@ pub async fn update_comment(
let mentions = scrape_text_for_mentions(&updated_comment_content); let mentions = scrape_text_for_mentions(&updated_comment_content);
let recipient_ids = send_local_notifs( let recipient_ids = send_local_notifs(
mentions, mentions,
&updated_comment, comment_id,
&local_user_view.person, &local_user_view.person,
&orig_comment.post,
false, false,
&context, &context,
) )

View File

@ -20,7 +20,7 @@ use lemmy_db_views_actor::structs::{
}; };
use lemmy_utils::{ use lemmy_utils::{
error::{LemmyError, LemmyErrorExt, LemmyErrorType}, error::{LemmyError, LemmyErrorExt, LemmyErrorType},
CACHE_DURATION_SHORT, CACHE_DURATION_API,
VERSION, VERSION,
}; };
use moka::future::Cache; use moka::future::Cache;
@ -34,7 +34,7 @@ pub async fn get_site(
static CACHE: Lazy<Cache<(), GetSiteResponse>> = Lazy::new(|| { static CACHE: Lazy<Cache<(), GetSiteResponse>> = Lazy::new(|| {
Cache::builder() Cache::builder()
.max_capacity(1) .max_capacity(1)
.time_to_live(CACHE_DURATION_SHORT) .time_to_live(CACHE_DURATION_API)
.build() .build()
}); });

View File

@ -159,8 +159,6 @@ impl ActivityHandler for CreateOrUpdateNote {
CommentAggregates::update_hot_rank(&mut context.pool(), comment.id).await?; CommentAggregates::update_hot_rank(&mut context.pool(), comment.id).await?;
let do_send_email = self.kind == CreateOrUpdateType::Create; let do_send_email = self.kind == CreateOrUpdateType::Create;
let post_id = comment.post_id;
let post = Post::read(&mut context.pool(), post_id).await?;
let actor = self.actor.dereference(context).await?; let actor = self.actor.dereference(context).await?;
// Note: // Note:
@ -169,7 +167,7 @@ impl ActivityHandler for CreateOrUpdateNote {
// anyway. // anyway.
// TODO: for compatibility with other projects, it would be much better to read this from cc or tags // TODO: for compatibility with other projects, it would be much better to read this from cc or tags
let mentions = scrape_text_for_mentions(&comment.content); let mentions = scrape_text_for_mentions(&comment.content);
send_local_notifs(mentions, &comment.0, &actor, &post, do_send_email, context).await?; send_local_notifs(mentions, comment.id, &actor, do_send_email, context).await?;
Ok(()) Ok(())
} }
} }

View File

@ -11,7 +11,7 @@ use lemmy_db_schema::{
}; };
use lemmy_utils::{ use lemmy_utils::{
error::{LemmyError, LemmyErrorType, LemmyResult}, error::{LemmyError, LemmyErrorType, LemmyResult},
CACHE_DURATION_SHORT, CACHE_DURATION_FEDERATION,
}; };
use moka::future::Cache; use moka::future::Cache;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
@ -127,7 +127,7 @@ pub(crate) async fn local_site_data_cached(
static CACHE: Lazy<Cache<(), Arc<LocalSiteData>>> = Lazy::new(|| { static CACHE: Lazy<Cache<(), Arc<LocalSiteData>>> = Lazy::new(|| {
Cache::builder() Cache::builder()
.max_capacity(1) .max_capacity(1)
.time_to_live(CACHE_DURATION_SHORT) .time_to_live(CACHE_DURATION_FEDERATION)
.build() .build()
}); });
Ok( Ok(

View File

@ -5,7 +5,7 @@ use crate::{
}; };
use diesel::{dsl::insert_into, result::Error}; use diesel::{dsl::insert_into, result::Error};
use diesel_async::RunQueryDsl; use diesel_async::RunQueryDsl;
use lemmy_utils::{error::LemmyError, CACHE_DURATION_SHORT}; use lemmy_utils::{error::LemmyError, CACHE_DURATION_API};
use moka::future::Cache; use moka::future::Cache;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
@ -21,7 +21,7 @@ impl LocalSite {
static CACHE: Lazy<Cache<(), LocalSite>> = Lazy::new(|| { static CACHE: Lazy<Cache<(), LocalSite>> = Lazy::new(|| {
Cache::builder() Cache::builder()
.max_capacity(1) .max_capacity(1)
.time_to_live(CACHE_DURATION_SHORT) .time_to_live(CACHE_DURATION_API)
.build() .build()
}); });
Ok( Ok(

View File

@ -36,7 +36,7 @@ pub struct Site {
pub inbox_url: DbUrl, pub inbox_url: DbUrl,
#[serde(skip)] #[serde(skip)]
pub private_key: Option<String>, pub private_key: Option<String>,
#[serde(skip)] // TODO: mark as `serde(skip)` in next major release as its not needed for api
pub public_key: String, pub public_key: String,
pub instance_id: InstanceId, pub instance_id: InstanceId,
/// If present, nsfw content is visible by default. Should be displayed by frontends/clients /// If present, nsfw content is visible by default. Should be displayed by frontends/clients

View File

@ -1,7 +1,7 @@
use anyhow::{anyhow, Context, Result}; use anyhow::{anyhow, Context, Result};
use diesel::prelude::*; use diesel::prelude::*;
use diesel_async::RunQueryDsl; use diesel_async::RunQueryDsl;
use lemmy_api_common::lemmy_utils::CACHE_DURATION_SHORT; use lemmy_api_common::lemmy_utils::CACHE_DURATION_FEDERATION;
use lemmy_apub::{ use lemmy_apub::{
activity_lists::SharedInboxActivities, activity_lists::SharedInboxActivities,
fetcher::{site_or_community_or_user::SiteOrCommunityOrUser, user_or_community::UserOrCommunity}, fetcher::{site_or_community_or_user::SiteOrCommunityOrUser, user_or_community::UserOrCommunity},
@ -169,8 +169,11 @@ pub(crate) async fn get_activity_cached(
/// return the most current activity id (with 1 second cache) /// return the most current activity id (with 1 second cache)
pub(crate) async fn get_latest_activity_id(pool: &mut DbPool<'_>) -> Result<ActivityId> { pub(crate) async fn get_latest_activity_id(pool: &mut DbPool<'_>) -> Result<ActivityId> {
static CACHE: Lazy<Cache<(), ActivityId>> = static CACHE: Lazy<Cache<(), ActivityId>> = Lazy::new(|| {
Lazy::new(|| Cache::builder().time_to_live(CACHE_DURATION_SHORT).build()); Cache::builder()
.time_to_live(CACHE_DURATION_FEDERATION)
.build()
});
CACHE CACHE
.try_get_with((), async { .try_get_with((), async {
use diesel::dsl::max; use diesel::dsl::max;

View File

@ -24,9 +24,11 @@ pub const VERSION: &str = env!("CARGO_PKG_VERSION");
pub const REQWEST_TIMEOUT: Duration = Duration::from_secs(10); pub const REQWEST_TIMEOUT: Duration = Duration::from_secs(10);
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
pub const CACHE_DURATION_SHORT: Duration = Duration::from_millis(500); pub const CACHE_DURATION_FEDERATION: Duration = Duration::from_millis(500);
#[cfg(not(debug_assertions))] #[cfg(not(debug_assertions))]
pub const CACHE_DURATION_SHORT: Duration = Duration::from_secs(60); pub const CACHE_DURATION_FEDERATION: Duration = Duration::from_secs(60);
pub const CACHE_DURATION_API: Duration = Duration::from_secs(1);
#[macro_export] #[macro_export]
macro_rules! location_info { macro_rules! location_info {

View File

@ -13,8 +13,17 @@ use structs::{DatabaseConnection, PictrsConfig, PictrsImageMode, Settings};
static DEFAULT_CONFIG_FILE: &str = "config/config.hjson"; static DEFAULT_CONFIG_FILE: &str = "config/config.hjson";
pub static SETTINGS: Lazy<Settings> = Lazy::new(|| { pub static SETTINGS: Lazy<Settings> = Lazy::new(|| {
Settings::init().expect("Failed to load settings file, see documentation (https://join-lemmy.org/docs/en/administration/configuration.html)") if env::var("LEMMY_INITIALIZE_WITH_DEFAULT_SETTINGS").is_ok() {
println!(
"LEMMY_INITIALIZE_WITH_DEFAULT_SETTINGS was set, any configuration file has been ignored."
);
println!("Use with other environment variables to configure this instance further; e.g. LEMMY_DATABASE_URL.");
Settings::default()
} else {
Settings::init().expect("Failed to load settings file, see documentation (https://join-lemmy.org/docs/en/administration/configuration.html).")
}
}); });
static WEBFINGER_REGEX: Lazy<Regex> = Lazy::new(|| { static WEBFINGER_REGEX: Lazy<Regex> = Lazy::new(|| {
Regex::new(&format!( Regex::new(&format!(
"^acct:([a-zA-Z0-9_]{{3,}})@{}$", "^acct:([a-zA-Z0-9_]{{3,}})@{}$",
@ -30,9 +39,7 @@ impl Settings {
/// `lemmy_db_schema/src/lib.rs::get_database_url_from_env()` /// `lemmy_db_schema/src/lib.rs::get_database_url_from_env()`
/// Warning: Only call this once. /// Warning: Only call this once.
pub(crate) fn init() -> Result<Self, LemmyError> { pub(crate) fn init() -> Result<Self, LemmyError> {
// Read the config file
let config = from_str::<Settings>(&Self::read_config_file()?)?; let config = from_str::<Settings>(&Self::read_config_file()?)?;
if config.hostname == "unset" { if config.hostname == "unset" {
Err(anyhow!("Hostname variable is not set!").into()) Err(anyhow!("Hostname variable is not set!").into())
} else { } else {

View File

@ -6,7 +6,7 @@ CWD="$(cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"
cd $CWD/../ cd $CWD/../
PACKAGE="$1" PACKAGE="$1"
echo "$PACKAGE" TEST="$2"
source scripts/start_dev_db.sh source scripts/start_dev_db.sh
@ -17,7 +17,7 @@ export RUST_BACKTRACE=1
if [ -n "$PACKAGE" ]; if [ -n "$PACKAGE" ];
then then
cargo test -p $PACKAGE --all-features --no-fail-fast cargo test -p $PACKAGE --all-features --no-fail-fast $TEST
else else
cargo test --workspace --no-fail-fast cargo test --workspace --no-fail-fast
fi fi