mirror of
https://github.com/LemmyNet/lemmy.git
synced 2025-09-03 03:33:50 +00:00
* Use either instead of manually implemented enums (fixes #5513) * reduce db reads
This commit is contained in:
parent
cc39ffeef3
commit
ad89b8e40a
32 changed files with 154 additions and 544 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -3212,6 +3212,7 @@ dependencies = [
|
|||
"async-trait",
|
||||
"chrono",
|
||||
"diesel",
|
||||
"either",
|
||||
"enum_delegate",
|
||||
"futures",
|
||||
"html2md",
|
||||
|
@ -3224,7 +3225,6 @@ dependencies = [
|
|||
"lemmy_utils",
|
||||
"moka",
|
||||
"pretty_assertions",
|
||||
"reqwest 0.12.12",
|
||||
"semver",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
|
|
@ -38,7 +38,6 @@ itertools = { workspace = true }
|
|||
uuid = { workspace = true }
|
||||
async-trait = "0.1.86"
|
||||
anyhow = { workspace = true }
|
||||
reqwest = { workspace = true }
|
||||
moka.workspace = true
|
||||
serde_with.workspace = true
|
||||
html2md = "0.2.15"
|
||||
|
@ -46,6 +45,7 @@ html2text = "0.14.0"
|
|||
stringreader = "0.1.1"
|
||||
enum_delegate = "0.2.0"
|
||||
semver = "1.0.25"
|
||||
either = "1.15.0"
|
||||
|
||||
[dev-dependencies]
|
||||
serial_test = { workspace = true }
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::{
|
||||
activities::send_lemmy_activity,
|
||||
activity_lists::AnnouncableActivities,
|
||||
fetcher::post_or_comment::PostOrComment,
|
||||
fetcher::PostOrComment,
|
||||
objects::{community::ApubCommunity, instance::ApubSite, person::ApubPerson},
|
||||
protocol::activities::community::announce::AnnounceActivity,
|
||||
};
|
||||
|
@ -96,8 +96,8 @@ async fn report_inboxes(
|
|||
|
||||
// also send report to user's home instance if possible
|
||||
let object_creator_id = match object_id.dereference_local(context).await? {
|
||||
PostOrComment::Post(p) => p.creator_id,
|
||||
PostOrComment::Comment(c) => c.creator_id,
|
||||
PostOrComment::Left(p) => p.creator_id,
|
||||
PostOrComment::Right(c) => c.creator_id,
|
||||
};
|
||||
let object_creator = Person::read(&mut context.pool(), object_creator_id).await?;
|
||||
let object_creator_site: Option<ApubSite> =
|
||||
|
|
|
@ -95,7 +95,7 @@ impl ActivityHandler for Report {
|
|||
let actor = self.actor.dereference(context).await?;
|
||||
let reason = self.reason()?;
|
||||
match self.object.dereference(context).await? {
|
||||
PostOrComment::Post(post) => {
|
||||
PostOrComment::Left(post) => {
|
||||
check_post_deleted_or_removed(&post)?;
|
||||
|
||||
let report_form = PostReportForm {
|
||||
|
@ -109,7 +109,7 @@ impl ActivityHandler for Report {
|
|||
};
|
||||
PostReport::report(&mut context.pool(), &report_form).await?;
|
||||
}
|
||||
PostOrComment::Comment(comment) => {
|
||||
PostOrComment::Right(comment) => {
|
||||
check_comment_deleted_or_removed(&comment)?;
|
||||
|
||||
let report_form = CommentReportForm {
|
||||
|
|
|
@ -87,10 +87,10 @@ impl ActivityHandler for ResolveReport {
|
|||
let reporter = self.object.actor.dereference(context).await?;
|
||||
let actor = self.actor.dereference(context).await?;
|
||||
match self.object.object.dereference(context).await? {
|
||||
PostOrComment::Post(post) => {
|
||||
PostOrComment::Left(post) => {
|
||||
PostReport::resolve_apub(&mut context.pool(), post.id, reporter.id, actor.id).await?;
|
||||
}
|
||||
PostOrComment::Comment(comment) => {
|
||||
PostOrComment::Right(comment) => {
|
||||
CommentReport::resolve_apub(&mut context.pool(), comment.id, reporter.id, actor.id).await?;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use super::send_activity_from_user_or_community;
|
||||
use crate::{
|
||||
activities::{generate_activity_id, send_lemmy_activity},
|
||||
activities::generate_activity_id,
|
||||
insert_received_activity,
|
||||
protocol::activities::following::{accept::AcceptFollow, follow::Follow},
|
||||
};
|
||||
|
@ -32,7 +33,7 @@ impl AcceptFollow {
|
|||
)?,
|
||||
};
|
||||
let inbox = ActivitySendTargets::to_inbox(person.shared_inbox_or_inbox());
|
||||
send_lemmy_activity(context, accept, &user_or_community, inbox, true).await
|
||||
send_activity_from_user_or_community(context, accept, user_or_community, inbox).await
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ use crate::{
|
|||
verify_person,
|
||||
verify_person_in_community,
|
||||
},
|
||||
fetcher::user_or_community::UserOrCommunity,
|
||||
fetcher::UserOrCommunity,
|
||||
insert_received_activity,
|
||||
objects::{community::ApubCommunity, person::ApubPerson},
|
||||
protocol::activities::following::{accept::AcceptFollow, follow::Follow},
|
||||
|
@ -79,7 +79,7 @@ impl ActivityHandler for Follow {
|
|||
async fn verify(&self, context: &Data<LemmyContext>) -> LemmyResult<()> {
|
||||
verify_person(&self.actor, context).await?;
|
||||
let object = self.object.dereference(context).await?;
|
||||
if let UserOrCommunity::Community(c) = object {
|
||||
if let UserOrCommunity::Right(c) = object {
|
||||
verify_person_in_community(&self.actor, &c, context).await?;
|
||||
}
|
||||
if let Some(to) = &self.to {
|
||||
|
@ -94,12 +94,12 @@ impl ActivityHandler for Follow {
|
|||
let actor = self.actor.dereference(context).await?;
|
||||
let object = self.object.dereference(context).await?;
|
||||
match object {
|
||||
UserOrCommunity::User(u) => {
|
||||
UserOrCommunity::Left(u) => {
|
||||
let form = PersonFollowerForm::new(u.id, actor.id, false);
|
||||
PersonActions::follow(&mut context.pool(), &form).await?;
|
||||
AcceptFollow::send(self, context).await?;
|
||||
}
|
||||
UserOrCommunity::Community(c) => {
|
||||
UserOrCommunity::Right(c) => {
|
||||
if c.visibility == CommunityVisibility::Private {
|
||||
let instance = Instance::read(&mut context.pool(), actor.instance_id).await?;
|
||||
if [Some("kbin"), Some("mbin")].contains(&instance.software.as_deref()) {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use super::generate_activity_id;
|
||||
use super::{generate_activity_id, send_lemmy_activity};
|
||||
use crate::{
|
||||
fetcher::UserOrCommunity,
|
||||
objects::{community::ApubCommunity, person::ApubPerson},
|
||||
protocol::activities::following::{
|
||||
accept::AcceptFollow,
|
||||
|
@ -8,14 +9,15 @@ use crate::{
|
|||
undo_follow::UndoFollow,
|
||||
},
|
||||
};
|
||||
use activitypub_federation::{config::Data, kinds::activity::FollowType};
|
||||
use activitypub_federation::{config::Data, kinds::activity::FollowType, traits::ActivityHandler};
|
||||
use lemmy_api_common::context::LemmyContext;
|
||||
use lemmy_db_schema::{
|
||||
newtypes::{CommunityId, PersonId},
|
||||
source::{community::Community, person::Person},
|
||||
source::{activity::ActivitySendTargets, community::Community, person::Person},
|
||||
traits::Crud,
|
||||
};
|
||||
use lemmy_utils::error::LemmyResult;
|
||||
use lemmy_utils::error::{LemmyError, LemmyResult};
|
||||
use serde::Serialize;
|
||||
|
||||
pub(crate) mod accept;
|
||||
pub(crate) mod follow;
|
||||
|
@ -62,3 +64,23 @@ pub async fn send_accept_or_reject_follow(
|
|||
RejectFollow::send(follow, context).await
|
||||
}
|
||||
}
|
||||
|
||||
/// Wrapper type which is needed because we cant implement ActorT for Either.
|
||||
async fn send_activity_from_user_or_community<Activity>(
|
||||
context: &Data<LemmyContext>,
|
||||
activity: Activity,
|
||||
user_or_community: UserOrCommunity,
|
||||
send_targets: ActivitySendTargets,
|
||||
) -> LemmyResult<()>
|
||||
where
|
||||
Activity: ActivityHandler + Serialize + Send + Sync + Clone + ActivityHandler<Error = LemmyError>,
|
||||
{
|
||||
match user_or_community {
|
||||
UserOrCommunity::Left(user) => {
|
||||
send_lemmy_activity(context, activity, &user, send_targets, true).await
|
||||
}
|
||||
UserOrCommunity::Right(community) => {
|
||||
send_lemmy_activity(context, activity, &community, send_targets, true).await
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use super::send_activity_from_user_or_community;
|
||||
use crate::{
|
||||
activities::{generate_activity_id, send_lemmy_activity},
|
||||
activities::generate_activity_id,
|
||||
insert_received_activity,
|
||||
protocol::activities::following::{follow::Follow, reject::RejectFollow},
|
||||
};
|
||||
|
@ -32,7 +33,7 @@ impl RejectFollow {
|
|||
)?,
|
||||
};
|
||||
let inbox = ActivitySendTargets::to_inbox(person.shared_inbox_or_inbox());
|
||||
send_lemmy_activity(context, reject, &user_or_community, inbox, true).await
|
||||
send_activity_from_user_or_community(context, reject, user_or_community, inbox).await
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{
|
||||
activities::{generate_activity_id, send_lemmy_activity, verify_person},
|
||||
fetcher::user_or_community::UserOrCommunity,
|
||||
fetcher::UserOrCommunity,
|
||||
insert_received_activity,
|
||||
objects::{community::ApubCommunity, person::ApubPerson},
|
||||
protocol::activities::following::{follow::Follow, undo_follow::UndoFollow},
|
||||
|
@ -74,10 +74,10 @@ impl ActivityHandler for UndoFollow {
|
|||
let object = self.object.object.dereference(context).await?;
|
||||
|
||||
match object {
|
||||
UserOrCommunity::User(u) => {
|
||||
UserOrCommunity::Left(u) => {
|
||||
PersonActions::unfollow(&mut context.pool(), person.id, u.id).await?;
|
||||
}
|
||||
UserOrCommunity::Community(c) => {
|
||||
UserOrCommunity::Right(c) => {
|
||||
CommunityActions::unfollow(&mut context.pool(), person.id, c.id).await?;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -122,7 +122,11 @@ pub(crate) fn verify_is_public(to: &[Url], cc: &[Url]) -> LemmyResult<()> {
|
|||
|
||||
/// Returns an error if object visibility doesnt match community visibility
|
||||
/// (ie content in private community must also be private).
|
||||
pub(crate) fn verify_visibility(to: &[Url], cc: &[Url], community: &Community) -> LemmyResult<()> {
|
||||
pub(crate) fn verify_visibility(
|
||||
to: &[Url],
|
||||
cc: &[Url],
|
||||
community: &ApubCommunity,
|
||||
) -> LemmyResult<()> {
|
||||
use CommunityVisibility::*;
|
||||
let object_is_public = [to, cc].iter().any(|set| set.contains(&public()));
|
||||
match community.visibility {
|
||||
|
@ -195,9 +199,8 @@ async fn send_lemmy_activity<Activity, ActorT>(
|
|||
sensitive: bool,
|
||||
) -> LemmyResult<()>
|
||||
where
|
||||
Activity: ActivityHandler + Serialize + Send + Sync + Clone,
|
||||
Activity: ActivityHandler + Serialize + Send + Sync + Clone + ActivityHandler<Error = LemmyError>,
|
||||
ActorT: Actor + GetActorType,
|
||||
Activity: ActivityHandler<Error = LemmyError>,
|
||||
{
|
||||
info!("Saving outgoing activity to queue {}", activity.id());
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::{
|
||||
activities::community::send_activity_in_community,
|
||||
activity_lists::AnnouncableActivities,
|
||||
fetcher::post_or_comment::PostOrComment,
|
||||
fetcher::PostOrComment,
|
||||
objects::{comment::ApubComment, community::ApubCommunity, person::ApubPerson, post::ApubPost},
|
||||
protocol::activities::voting::{
|
||||
undo_vote::UndoVote,
|
||||
|
|
|
@ -66,8 +66,8 @@ impl ActivityHandler for UndoVote {
|
|||
let actor = self.actor.dereference(context).await?;
|
||||
let object = self.object.object.dereference(context).await?;
|
||||
match object {
|
||||
PostOrComment::Post(p) => undo_vote_post(actor, &p, context).await,
|
||||
PostOrComment::Comment(c) => undo_vote_comment(actor, &c, context).await,
|
||||
PostOrComment::Left(p) => undo_vote_post(actor, &p, context).await,
|
||||
PostOrComment::Right(c) => undo_vote_comment(actor, &c, context).await,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,8 +72,8 @@ impl ActivityHandler for Vote {
|
|||
.unwrap_or_default();
|
||||
|
||||
let (downvote_setting, upvote_setting) = match object {
|
||||
PostOrComment::Post(_) => (local_site.post_downvotes, local_site.post_upvotes),
|
||||
PostOrComment::Comment(_) => (local_site.comment_downvotes, local_site.comment_upvotes),
|
||||
PostOrComment::Left(_) => (local_site.post_downvotes, local_site.post_upvotes),
|
||||
PostOrComment::Right(_) => (local_site.comment_downvotes, local_site.comment_upvotes),
|
||||
};
|
||||
|
||||
// Don't allow dislikes for either disabled, or local only votes
|
||||
|
@ -83,14 +83,14 @@ impl ActivityHandler for Vote {
|
|||
if downvote_fail || upvote_fail {
|
||||
// If this is a rejection, undo the vote
|
||||
match object {
|
||||
PostOrComment::Post(p) => undo_vote_post(actor, &p, context).await,
|
||||
PostOrComment::Comment(c) => undo_vote_comment(actor, &c, context).await,
|
||||
PostOrComment::Left(p) => undo_vote_post(actor, &p, context).await,
|
||||
PostOrComment::Right(c) => undo_vote_comment(actor, &c, context).await,
|
||||
}
|
||||
} else {
|
||||
// Otherwise apply the vote normally
|
||||
match object {
|
||||
PostOrComment::Post(p) => vote_post(&self.kind, actor, &p, context).await,
|
||||
PostOrComment::Comment(c) => vote_comment(&self.kind, actor, &c, context).await,
|
||||
PostOrComment::Left(p) => vote_post(&self.kind, actor, &p, context).await,
|
||||
PostOrComment::Right(c) => vote_comment(&self.kind, actor, &c, context).await,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::fetcher::{
|
||||
post_or_comment::PostOrComment,
|
||||
search::{search_query_to_object_id, search_query_to_object_id_local, SearchableObjects},
|
||||
user_or_community::UserOrCommunity,
|
||||
PostOrComment,
|
||||
UserOrCommunity,
|
||||
};
|
||||
use activitypub_federation::config::Data;
|
||||
use actix_web::web::{Json, Query};
|
||||
|
@ -59,21 +59,21 @@ async fn convert_response(
|
|||
let local_instance_id = site_view.site.instance_id;
|
||||
|
||||
match object {
|
||||
SearchableObjects::PostOrComment(pc) => match *pc {
|
||||
PostOrComment::Post(p) => {
|
||||
SearchableObjects::Left(pc) => match pc {
|
||||
PostOrComment::Left(p) => {
|
||||
res.post =
|
||||
Some(PostView::read(pool, p.id, local_user.as_ref(), local_instance_id, is_admin).await?)
|
||||
}
|
||||
PostOrComment::Comment(c) => {
|
||||
PostOrComment::Right(c) => {
|
||||
res.comment =
|
||||
Some(CommentView::read(pool, c.id, local_user.as_ref(), local_instance_id).await?)
|
||||
}
|
||||
},
|
||||
SearchableObjects::PersonOrCommunity(pc) => match *pc {
|
||||
UserOrCommunity::User(u) => {
|
||||
SearchableObjects::Right(pc) => match pc {
|
||||
UserOrCommunity::Left(u) => {
|
||||
res.person = Some(PersonView::read(pool, u.id, local_instance_id, is_admin).await?)
|
||||
}
|
||||
UserOrCommunity::Community(c) => {
|
||||
UserOrCommunity::Right(c) => {
|
||||
res.community = Some(CommunityView::read(pool, c.id, local_user.as_ref(), is_admin).await?)
|
||||
}
|
||||
},
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use super::{search::SearchableObjects, user_or_community::UserOrCommunity};
|
||||
use crate::fetcher::post_or_comment::PostOrComment;
|
||||
use super::{search::SearchableObjects, UserOrCommunity};
|
||||
use crate::fetcher::PostOrComment;
|
||||
use activitypub_federation::{config::Data, fetch::object_id::ObjectId};
|
||||
use lemmy_api_common::context::LemmyContext;
|
||||
use lemmy_db_schema::{newtypes::InstanceId, source::instance::Instance};
|
||||
|
@ -57,17 +57,17 @@ pub(crate) async fn to_local_url(url: &str, context: &Data<LemmyContext>) -> Opt
|
|||
}
|
||||
let dereferenced = object_id.dereference_local(context).await.ok()?;
|
||||
match dereferenced {
|
||||
SearchableObjects::PostOrComment(pc) => match *pc {
|
||||
PostOrComment::Post(post) => post.local_url(context.settings()),
|
||||
PostOrComment::Comment(comment) => comment.local_url(context.settings()),
|
||||
SearchableObjects::Left(pc) => match pc {
|
||||
PostOrComment::Left(post) => post.local_url(context.settings()),
|
||||
PostOrComment::Right(comment) => comment.local_url(context.settings()),
|
||||
}
|
||||
.ok()
|
||||
.map(Into::into),
|
||||
SearchableObjects::PersonOrCommunity(pc) => match *pc {
|
||||
UserOrCommunity::User(user) => {
|
||||
SearchableObjects::Right(pc) => match pc {
|
||||
UserOrCommunity::Left(user) => {
|
||||
format_actor_url(&user.name, "u", user.instance_id, context).await
|
||||
}
|
||||
UserOrCommunity::Community(community) => {
|
||||
UserOrCommunity::Right(community) => {
|
||||
format_actor_url(&community.name, "c", community.instance_id, context).await
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,20 +1,31 @@
|
|||
use crate::objects::{
|
||||
comment::ApubComment,
|
||||
community::ApubCommunity,
|
||||
instance::ApubSite,
|
||||
person::ApubPerson,
|
||||
post::ApubPost,
|
||||
};
|
||||
use activitypub_federation::{
|
||||
config::Data,
|
||||
fetch::webfinger::webfinger_resolve_actor,
|
||||
traits::{Actor, Object},
|
||||
};
|
||||
use diesel::NotFound;
|
||||
use either::Either;
|
||||
use itertools::Itertools;
|
||||
use lemmy_api_common::{context::LemmyContext, LemmyErrorType};
|
||||
use lemmy_db_schema::traits::ApubActor;
|
||||
use lemmy_db_schema::{newtypes::InstanceId, traits::ApubActor};
|
||||
use lemmy_db_views::structs::LocalUserView;
|
||||
use lemmy_utils::error::{LemmyError, LemmyResult};
|
||||
|
||||
pub(crate) mod markdown_links;
|
||||
pub mod post_or_comment;
|
||||
pub mod search;
|
||||
pub mod site_or_community_or_user;
|
||||
pub mod user_or_community;
|
||||
|
||||
pub(crate) type PostOrComment = Either<ApubPost, ApubComment>;
|
||||
|
||||
pub type SiteOrCommunityOrUser = Either<ApubSite, UserOrCommunity>;
|
||||
|
||||
pub type UserOrCommunity = Either<ApubPerson, ApubCommunity>;
|
||||
|
||||
/// Resolve actor identifier like `!news@example.com` to user or community object.
|
||||
///
|
||||
|
@ -67,3 +78,11 @@ where
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn get_instance_id(s: &SiteOrCommunityOrUser) -> InstanceId {
|
||||
match s {
|
||||
SiteOrCommunityOrUser::Left(s) => s.instance_id,
|
||||
SiteOrCommunityOrUser::Right(UserOrCommunity::Left(u)) => u.instance_id,
|
||||
SiteOrCommunityOrUser::Right(UserOrCommunity::Right(c)) => c.instance_id,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,97 +0,0 @@
|
|||
use crate::{
|
||||
objects::{comment::ApubComment, community::ApubCommunity, post::ApubPost},
|
||||
protocol::{
|
||||
objects::{note::Note, page::Page},
|
||||
InCommunity,
|
||||
},
|
||||
};
|
||||
use activitypub_federation::{config::Data, traits::Object};
|
||||
use chrono::{DateTime, Utc};
|
||||
use lemmy_api_common::context::LemmyContext;
|
||||
use lemmy_db_schema::{
|
||||
source::{community::Community, post::Post},
|
||||
traits::Crud,
|
||||
};
|
||||
use lemmy_utils::error::{LemmyError, LemmyResult};
|
||||
use serde::Deserialize;
|
||||
use url::Url;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum PostOrComment {
|
||||
Post(ApubPost),
|
||||
Comment(ApubComment),
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum PageOrNote {
|
||||
Page(Box<Page>),
|
||||
Note(Box<Note>),
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl Object for PostOrComment {
|
||||
type DataType = LemmyContext;
|
||||
type Kind = PageOrNote;
|
||||
type Error = LemmyError;
|
||||
|
||||
fn last_refreshed_at(&self) -> Option<DateTime<Utc>> {
|
||||
None
|
||||
}
|
||||
|
||||
async fn read_from_id(object_id: Url, data: &Data<Self::DataType>) -> LemmyResult<Option<Self>> {
|
||||
let post = ApubPost::read_from_id(object_id.clone(), data).await?;
|
||||
Ok(match post {
|
||||
Some(o) => Some(PostOrComment::Post(o)),
|
||||
None => ApubComment::read_from_id(object_id, data)
|
||||
.await?
|
||||
.map(PostOrComment::Comment),
|
||||
})
|
||||
}
|
||||
|
||||
async fn delete(self, data: &Data<Self::DataType>) -> LemmyResult<()> {
|
||||
match self {
|
||||
PostOrComment::Post(p) => p.delete(data).await,
|
||||
PostOrComment::Comment(c) => c.delete(data).await,
|
||||
}
|
||||
}
|
||||
|
||||
async fn into_json(self, data: &Data<Self::DataType>) -> LemmyResult<Self::Kind> {
|
||||
Ok(match self {
|
||||
PostOrComment::Post(p) => PageOrNote::Page(Box::new(p.into_json(data).await?)),
|
||||
PostOrComment::Comment(c) => PageOrNote::Note(Box::new(c.into_json(data).await?)),
|
||||
})
|
||||
}
|
||||
|
||||
async fn verify(
|
||||
apub: &Self::Kind,
|
||||
expected_domain: &Url,
|
||||
data: &Data<Self::DataType>,
|
||||
) -> LemmyResult<()> {
|
||||
match apub {
|
||||
PageOrNote::Page(a) => ApubPost::verify(a, expected_domain, data).await,
|
||||
PageOrNote::Note(a) => ApubComment::verify(a, expected_domain, data).await,
|
||||
}
|
||||
}
|
||||
|
||||
async fn from_json(apub: PageOrNote, context: &Data<LemmyContext>) -> LemmyResult<Self> {
|
||||
Ok(match apub {
|
||||
PageOrNote::Page(p) => PostOrComment::Post(ApubPost::from_json(*p, context).await?),
|
||||
PageOrNote::Note(n) => PostOrComment::Comment(ApubComment::from_json(*n, context).await?),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl InCommunity for PostOrComment {
|
||||
async fn community(&self, context: &Data<LemmyContext>) -> LemmyResult<ApubCommunity> {
|
||||
let cid = match self {
|
||||
PostOrComment::Post(p) => p.community_id,
|
||||
PostOrComment::Comment(c) => {
|
||||
Post::read(&mut context.pool(), c.post_id)
|
||||
.await?
|
||||
.community_id
|
||||
}
|
||||
};
|
||||
Ok(Community::read(&mut context.pool(), cid).await?.into())
|
||||
}
|
||||
}
|
|
@ -1,14 +1,12 @@
|
|||
use super::post_or_comment::{PageOrNote, PostOrComment};
|
||||
use crate::fetcher::user_or_community::{PersonOrGroup, UserOrCommunity};
|
||||
use super::PostOrComment;
|
||||
use crate::fetcher::UserOrCommunity;
|
||||
use activitypub_federation::{
|
||||
config::Data,
|
||||
fetch::{object_id::ObjectId, webfinger::webfinger_resolve_actor},
|
||||
traits::Object,
|
||||
};
|
||||
use chrono::{DateTime, Utc};
|
||||
use either::Either;
|
||||
use lemmy_api_common::context::LemmyContext;
|
||||
use lemmy_utils::error::{LemmyError, LemmyResult};
|
||||
use serde::Deserialize;
|
||||
use lemmy_utils::error::LemmyResult;
|
||||
use url::Url;
|
||||
|
||||
/// Converts search query to object id. The query can either be an URL, which will be treated as
|
||||
|
@ -28,9 +26,9 @@ pub(crate) async fn search_query_to_object_id(
|
|||
if query.starts_with('!') || query.starts_with('@') {
|
||||
query.remove(0);
|
||||
}
|
||||
SearchableObjects::PersonOrCommunity(Box::new(
|
||||
SearchableObjects::Right(
|
||||
webfinger_resolve_actor::<LemmyContext, UserOrCommunity>(&query, context).await?,
|
||||
))
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -46,88 +44,4 @@ pub(crate) async fn search_query_to_object_id_local(
|
|||
ObjectId::from(url).dereference_local(context).await
|
||||
}
|
||||
|
||||
/// The types of ActivityPub objects that can be fetched directly by searching for their ID.
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum SearchableObjects {
|
||||
PostOrComment(Box<PostOrComment>),
|
||||
PersonOrCommunity(Box<UserOrCommunity>),
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub(crate) enum SearchableKinds {
|
||||
PageOrNote(Box<PageOrNote>),
|
||||
PersonOrGroup(Box<PersonOrGroup>),
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl Object for SearchableObjects {
|
||||
type DataType = LemmyContext;
|
||||
type Kind = SearchableKinds;
|
||||
type Error = LemmyError;
|
||||
|
||||
fn last_refreshed_at(&self) -> Option<DateTime<Utc>> {
|
||||
match self {
|
||||
SearchableObjects::PostOrComment(p) => p.last_refreshed_at(),
|
||||
SearchableObjects::PersonOrCommunity(p) => p.last_refreshed_at(),
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: this is inefficient, because if the object is not in local db, it will run 4 db queries
|
||||
// before finally returning an error. it would be nice if we could check all 4 tables in
|
||||
// a single query.
|
||||
// we could skip this and always return an error, but then it would always fetch objects
|
||||
// over http, and not be able to mark objects as deleted that were deleted by remote server.
|
||||
async fn read_from_id(
|
||||
object_id: Url,
|
||||
context: &Data<Self::DataType>,
|
||||
) -> LemmyResult<Option<Self>> {
|
||||
let uc = UserOrCommunity::read_from_id(object_id.clone(), context).await?;
|
||||
if let Some(uc) = uc {
|
||||
return Ok(Some(SearchableObjects::PersonOrCommunity(Box::new(uc))));
|
||||
}
|
||||
let pc = PostOrComment::read_from_id(object_id.clone(), context).await?;
|
||||
if let Some(pc) = pc {
|
||||
return Ok(Some(SearchableObjects::PostOrComment(Box::new(pc))));
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
async fn delete(self, data: &Data<Self::DataType>) -> LemmyResult<()> {
|
||||
match self {
|
||||
SearchableObjects::PostOrComment(pc) => pc.delete(data).await,
|
||||
SearchableObjects::PersonOrCommunity(pc) => pc.delete(data).await,
|
||||
}
|
||||
}
|
||||
|
||||
async fn into_json(self, data: &Data<Self::DataType>) -> LemmyResult<Self::Kind> {
|
||||
use SearchableObjects::*;
|
||||
Ok(match self {
|
||||
PostOrComment(pc) => SearchableKinds::PageOrNote(Box::new(pc.into_json(data).await?)),
|
||||
PersonOrCommunity(pc) => SearchableKinds::PersonOrGroup(Box::new(pc.into_json(data).await?)),
|
||||
})
|
||||
}
|
||||
|
||||
async fn verify(
|
||||
apub: &Self::Kind,
|
||||
expected_domain: &Url,
|
||||
data: &Data<Self::DataType>,
|
||||
) -> LemmyResult<()> {
|
||||
use SearchableKinds::*;
|
||||
match apub {
|
||||
PageOrNote(pn) => PostOrComment::verify(pn, expected_domain, data).await,
|
||||
PersonOrGroup(pg) => UserOrCommunity::verify(pg, expected_domain, data).await,
|
||||
}
|
||||
}
|
||||
|
||||
async fn from_json(apub: Self::Kind, context: &Data<LemmyContext>) -> LemmyResult<Self> {
|
||||
use SearchableKinds::*;
|
||||
use SearchableObjects as SO;
|
||||
Ok(match apub {
|
||||
PageOrNote(pg) => SO::PostOrComment(Box::new(PostOrComment::from_json(*pg, context).await?)),
|
||||
PersonOrGroup(pg) => {
|
||||
SO::PersonOrCommunity(Box::new(UserOrCommunity::from_json(*pg, context).await?))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
pub(crate) type SearchableObjects = Either<PostOrComment, UserOrCommunity>;
|
||||
|
|
|
@ -1,136 +0,0 @@
|
|||
use crate::{
|
||||
fetcher::user_or_community::{PersonOrGroup, UserOrCommunity},
|
||||
objects::{community::ApubCommunity, instance::ApubSite, person::ApubPerson},
|
||||
protocol::objects::instance::Instance,
|
||||
};
|
||||
use activitypub_federation::{
|
||||
config::Data,
|
||||
traits::{Actor, Object},
|
||||
};
|
||||
use chrono::{DateTime, Utc};
|
||||
use lemmy_api_common::context::LemmyContext;
|
||||
use lemmy_db_schema::newtypes::InstanceId;
|
||||
use lemmy_utils::error::{LemmyError, LemmyResult};
|
||||
use reqwest::Url;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
// todo: maybe this enum should be somewhere else?
|
||||
#[derive(Debug)]
|
||||
pub enum SiteOrCommunityOrUser {
|
||||
Site(ApubSite),
|
||||
UserOrCommunity(UserOrCommunity),
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
#[serde(untagged)]
|
||||
pub enum SiteOrPersonOrGroup {
|
||||
Instance(Instance),
|
||||
PersonOrGroup(PersonOrGroup),
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl Object for SiteOrCommunityOrUser {
|
||||
type DataType = LemmyContext;
|
||||
type Kind = SiteOrPersonOrGroup;
|
||||
type Error = LemmyError;
|
||||
|
||||
fn last_refreshed_at(&self) -> Option<DateTime<Utc>> {
|
||||
Some(match self {
|
||||
SiteOrCommunityOrUser::Site(p) => p.last_refreshed_at,
|
||||
SiteOrCommunityOrUser::UserOrCommunity(p) => p.last_refreshed_at()?,
|
||||
})
|
||||
}
|
||||
|
||||
async fn read_from_id(object_id: Url, data: &Data<Self::DataType>) -> LemmyResult<Option<Self>> {
|
||||
let site = ApubSite::read_from_id(object_id.clone(), data).await?;
|
||||
Ok(match site {
|
||||
Some(o) => Some(SiteOrCommunityOrUser::Site(o)),
|
||||
None => UserOrCommunity::read_from_id(object_id, data)
|
||||
.await?
|
||||
.map(SiteOrCommunityOrUser::UserOrCommunity),
|
||||
})
|
||||
}
|
||||
|
||||
async fn delete(self, data: &Data<Self::DataType>) -> LemmyResult<()> {
|
||||
match self {
|
||||
SiteOrCommunityOrUser::Site(p) => p.delete(data).await,
|
||||
SiteOrCommunityOrUser::UserOrCommunity(p) => p.delete(data).await,
|
||||
}
|
||||
}
|
||||
|
||||
async fn into_json(self, data: &Data<Self::DataType>) -> LemmyResult<Self::Kind> {
|
||||
Ok(match self {
|
||||
SiteOrCommunityOrUser::Site(p) => SiteOrPersonOrGroup::Instance(p.into_json(data).await?),
|
||||
SiteOrCommunityOrUser::UserOrCommunity(p) => {
|
||||
SiteOrPersonOrGroup::PersonOrGroup(p.into_json(data).await?)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
async fn verify(
|
||||
apub: &Self::Kind,
|
||||
expected_domain: &Url,
|
||||
data: &Data<Self::DataType>,
|
||||
) -> LemmyResult<()> {
|
||||
match apub {
|
||||
SiteOrPersonOrGroup::Instance(a) => ApubSite::verify(a, expected_domain, data).await,
|
||||
SiteOrPersonOrGroup::PersonOrGroup(a) => {
|
||||
UserOrCommunity::verify(a, expected_domain, data).await
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn from_json(apub: Self::Kind, data: &Data<Self::DataType>) -> LemmyResult<Self> {
|
||||
Ok(match apub {
|
||||
SiteOrPersonOrGroup::Instance(a) => {
|
||||
SiteOrCommunityOrUser::Site(ApubSite::from_json(a, data).await?)
|
||||
}
|
||||
SiteOrPersonOrGroup::PersonOrGroup(a) => SiteOrCommunityOrUser::UserOrCommunity(match a {
|
||||
PersonOrGroup::Person(p) => UserOrCommunity::User(ApubPerson::from_json(p, data).await?),
|
||||
PersonOrGroup::Group(g) => {
|
||||
UserOrCommunity::Community(ApubCommunity::from_json(g, data).await?)
|
||||
}
|
||||
}),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Actor for SiteOrCommunityOrUser {
|
||||
fn id(&self) -> Url {
|
||||
match self {
|
||||
SiteOrCommunityOrUser::Site(u) => u.id(),
|
||||
SiteOrCommunityOrUser::UserOrCommunity(c) => c.id(),
|
||||
}
|
||||
}
|
||||
|
||||
fn public_key_pem(&self) -> &str {
|
||||
match self {
|
||||
SiteOrCommunityOrUser::Site(p) => p.public_key_pem(),
|
||||
SiteOrCommunityOrUser::UserOrCommunity(p) => p.public_key_pem(),
|
||||
}
|
||||
}
|
||||
|
||||
fn private_key_pem(&self) -> Option<String> {
|
||||
match self {
|
||||
SiteOrCommunityOrUser::Site(p) => p.private_key_pem(),
|
||||
SiteOrCommunityOrUser::UserOrCommunity(p) => p.private_key_pem(),
|
||||
}
|
||||
}
|
||||
|
||||
fn inbox(&self) -> Url {
|
||||
match self {
|
||||
SiteOrCommunityOrUser::Site(u) => u.inbox(),
|
||||
SiteOrCommunityOrUser::UserOrCommunity(c) => c.inbox(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl SiteOrCommunityOrUser {
|
||||
pub fn instance_id(&self) -> InstanceId {
|
||||
match self {
|
||||
SiteOrCommunityOrUser::Site(s) => s.instance_id,
|
||||
SiteOrCommunityOrUser::UserOrCommunity(UserOrCommunity::User(u)) => u.instance_id,
|
||||
SiteOrCommunityOrUser::UserOrCommunity(UserOrCommunity::Community(c)) => c.instance_id,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,131 +0,0 @@
|
|||
use crate::{
|
||||
activities::GetActorType,
|
||||
objects::{community::ApubCommunity, person::ApubPerson},
|
||||
protocol::objects::{group::Group, person::Person},
|
||||
};
|
||||
use activitypub_federation::{
|
||||
config::Data,
|
||||
traits::{Actor, Object},
|
||||
};
|
||||
use chrono::{DateTime, Utc};
|
||||
use lemmy_api_common::context::LemmyContext;
|
||||
use lemmy_db_schema_file::enums::ActorType;
|
||||
use lemmy_utils::error::{LemmyError, LemmyResult};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use url::Url;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum UserOrCommunity {
|
||||
User(ApubPerson),
|
||||
Community(ApubCommunity),
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
#[serde(untagged)]
|
||||
pub enum PersonOrGroup {
|
||||
Person(Person),
|
||||
Group(Group),
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
|
||||
pub enum PersonOrGroupType {
|
||||
Person,
|
||||
Group,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl Object for UserOrCommunity {
|
||||
type DataType = LemmyContext;
|
||||
type Kind = PersonOrGroup;
|
||||
type Error = LemmyError;
|
||||
|
||||
fn last_refreshed_at(&self) -> Option<DateTime<Utc>> {
|
||||
Some(match self {
|
||||
UserOrCommunity::User(p) => p.last_refreshed_at,
|
||||
UserOrCommunity::Community(p) => p.last_refreshed_at,
|
||||
})
|
||||
}
|
||||
|
||||
async fn read_from_id(object_id: Url, data: &Data<Self::DataType>) -> LemmyResult<Option<Self>> {
|
||||
let person = ApubPerson::read_from_id(object_id.clone(), data).await?;
|
||||
Ok(match person {
|
||||
Some(o) => Some(UserOrCommunity::User(o)),
|
||||
None => ApubCommunity::read_from_id(object_id, data)
|
||||
.await?
|
||||
.map(UserOrCommunity::Community),
|
||||
})
|
||||
}
|
||||
|
||||
async fn delete(self, data: &Data<Self::DataType>) -> LemmyResult<()> {
|
||||
match self {
|
||||
UserOrCommunity::User(p) => p.delete(data).await,
|
||||
UserOrCommunity::Community(p) => p.delete(data).await,
|
||||
}
|
||||
}
|
||||
|
||||
async fn into_json(self, data: &Data<Self::DataType>) -> LemmyResult<Self::Kind> {
|
||||
Ok(match self {
|
||||
UserOrCommunity::User(p) => PersonOrGroup::Person(p.into_json(data).await?),
|
||||
UserOrCommunity::Community(p) => PersonOrGroup::Group(p.into_json(data).await?),
|
||||
})
|
||||
}
|
||||
|
||||
async fn verify(
|
||||
apub: &Self::Kind,
|
||||
expected_domain: &Url,
|
||||
data: &Data<Self::DataType>,
|
||||
) -> LemmyResult<()> {
|
||||
match apub {
|
||||
PersonOrGroup::Person(a) => ApubPerson::verify(a, expected_domain, data).await,
|
||||
PersonOrGroup::Group(a) => ApubCommunity::verify(a, expected_domain, data).await,
|
||||
}
|
||||
}
|
||||
|
||||
async fn from_json(apub: Self::Kind, data: &Data<Self::DataType>) -> LemmyResult<Self> {
|
||||
Ok(match apub {
|
||||
PersonOrGroup::Person(p) => UserOrCommunity::User(ApubPerson::from_json(p, data).await?),
|
||||
PersonOrGroup::Group(p) => {
|
||||
UserOrCommunity::Community(ApubCommunity::from_json(p, data).await?)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Actor for UserOrCommunity {
|
||||
fn id(&self) -> Url {
|
||||
match self {
|
||||
UserOrCommunity::User(u) => u.id(),
|
||||
UserOrCommunity::Community(c) => c.id(),
|
||||
}
|
||||
}
|
||||
|
||||
fn public_key_pem(&self) -> &str {
|
||||
match self {
|
||||
UserOrCommunity::User(p) => p.public_key_pem(),
|
||||
UserOrCommunity::Community(p) => p.public_key_pem(),
|
||||
}
|
||||
}
|
||||
|
||||
fn private_key_pem(&self) -> Option<String> {
|
||||
match self {
|
||||
UserOrCommunity::User(p) => p.private_key_pem(),
|
||||
UserOrCommunity::Community(p) => p.private_key_pem(),
|
||||
}
|
||||
}
|
||||
|
||||
fn inbox(&self) -> Url {
|
||||
match self {
|
||||
UserOrCommunity::User(p) => p.inbox(),
|
||||
UserOrCommunity::Community(p) => p.inbox(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl GetActorType for UserOrCommunity {
|
||||
fn actor_type(&self) -> ActorType {
|
||||
match self {
|
||||
UserOrCommunity::User(p) => p.actor_type(),
|
||||
UserOrCommunity::Community(p) => p.actor_type(),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,7 +6,7 @@ use crate::{
|
|||
community_moderators::ApubCommunityModerators,
|
||||
community_outbox::ApubCommunityOutbox,
|
||||
},
|
||||
fetcher::site_or_community_or_user::SiteOrCommunityOrUser,
|
||||
fetcher::{get_instance_id, SiteOrCommunityOrUser},
|
||||
http::{check_community_fetchable, create_apub_response, create_apub_tombstone_response},
|
||||
objects::community::ApubCommunity,
|
||||
};
|
||||
|
@ -90,12 +90,12 @@ async fn check_is_follower(
|
|||
let signing_actor = signing_actor::<SiteOrCommunityOrUser>(&request, None, &context).await?;
|
||||
CommunityFollowerView::check_has_followers_from_instance(
|
||||
community.id,
|
||||
signing_actor.instance_id(),
|
||||
get_instance_id(&signing_actor),
|
||||
&mut context.pool(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
let instance_id = is_follower.dereference(&context).await?.instance_id();
|
||||
let instance_id = get_instance_id(&is_follower.dereference(&context).await?);
|
||||
let has_followers = CommunityFollowerView::check_has_followers_from_instance(
|
||||
community.id,
|
||||
instance_id,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{
|
||||
activity_lists::SharedInboxActivities,
|
||||
fetcher::{site_or_community_or_user::SiteOrCommunityOrUser, user_or_community::UserOrCommunity},
|
||||
fetcher::{get_instance_id, SiteOrCommunityOrUser, UserOrCommunity},
|
||||
protocol::objects::tombstone::Tombstone,
|
||||
FEDERATION_CONTEXT,
|
||||
};
|
||||
|
@ -144,7 +144,7 @@ async fn check_community_content_fetchable(
|
|||
Ok(
|
||||
CommunityFollowerView::check_has_followers_from_instance(
|
||||
community.id,
|
||||
signing_actor.instance_id(),
|
||||
get_instance_id(&signing_actor),
|
||||
&mut context.pool(),
|
||||
)
|
||||
.await?,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::fetcher::post_or_comment::PostOrComment;
|
||||
use crate::fetcher::PostOrComment;
|
||||
use activitypub_federation::{
|
||||
config::{Data, UrlVerifier},
|
||||
error::Error as ActivityPubError,
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
use super::{handle_community_moderators, person::ApubPerson};
|
||||
use crate::{
|
||||
activities::GetActorType,
|
||||
fetcher::{
|
||||
markdown_links::markdown_rewrite_remote_links_opt,
|
||||
user_or_community::PersonOrGroupType,
|
||||
},
|
||||
fetcher::markdown_links::markdown_rewrite_remote_links_opt,
|
||||
objects::{instance::fetch_instance_actor_for_object, read_from_string_or_source_opt},
|
||||
protocol::{
|
||||
objects::{group::Group, AttributedTo, LanguageTag},
|
||||
objects::{group::Group, AttributedTo, LanguageTag, PersonOrGroupType},
|
||||
ImageObject,
|
||||
Source,
|
||||
},
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::{
|
||||
fetcher::post_or_comment::PostOrComment,
|
||||
fetcher::PostOrComment,
|
||||
objects::{community::ApubCommunity, person::ApubPerson},
|
||||
protocol::InCommunity,
|
||||
};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{fetcher::user_or_community::UserOrCommunity, objects::person::ApubPerson};
|
||||
use crate::{fetcher::UserOrCommunity, objects::person::ApubPerson};
|
||||
use activitypub_federation::{
|
||||
fetch::object_id::ObjectId,
|
||||
kinds::activity::FollowType,
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
use crate::{
|
||||
fetcher::post_or_comment::PostOrComment,
|
||||
fetcher::PostOrComment,
|
||||
objects::{community::ApubCommunity, person::ApubPerson},
|
||||
protocol::InCommunity,
|
||||
};
|
||||
use activitypub_federation::{config::Data, fetch::object_id::ObjectId};
|
||||
use either::Either;
|
||||
use lemmy_api_common::context::LemmyContext;
|
||||
use lemmy_db_schema::{source::community::Community, traits::Crud};
|
||||
use lemmy_db_views::structs::{PostView, SiteView};
|
||||
use lemmy_utils::error::{FederationError, LemmyError, LemmyResult};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use strum::Display;
|
||||
|
@ -49,12 +52,21 @@ impl From<&VoteType> for i16 {
|
|||
|
||||
impl InCommunity for Vote {
|
||||
async fn community(&self, context: &Data<LemmyContext>) -> LemmyResult<ApubCommunity> {
|
||||
let community = self
|
||||
.object
|
||||
.dereference(context)
|
||||
.await?
|
||||
.community(context)
|
||||
.await?;
|
||||
Ok(community)
|
||||
let community = match self.object.dereference(context).await? {
|
||||
Either::Left(p) => Community::read(&mut context.pool(), p.community_id).await?,
|
||||
Either::Right(c) => {
|
||||
let site_view = SiteView::read_local(&mut context.pool()).await?;
|
||||
PostView::read(
|
||||
&mut context.pool(),
|
||||
c.post_id,
|
||||
None,
|
||||
site_view.instance.id,
|
||||
false,
|
||||
)
|
||||
.await?
|
||||
.community
|
||||
}
|
||||
};
|
||||
Ok(community.into())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{
|
||||
collections::community_moderators::ApubCommunityModerators,
|
||||
fetcher::user_or_community::{PersonOrGroupType, UserOrCommunity},
|
||||
fetcher::UserOrCommunity,
|
||||
objects::person::ApubPerson,
|
||||
};
|
||||
use activitypub_federation::fetch::{collection_id::CollectionId, object_id::ObjectId};
|
||||
|
@ -140,6 +140,12 @@ pub(crate) enum AttributedTo {
|
|||
Peertube(Vec<AttributedToPeertube>),
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
|
||||
pub(crate) enum PersonOrGroupType {
|
||||
Person,
|
||||
Group,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub(crate) struct AttributedToPeertube {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::{
|
||||
fetcher::post_or_comment::PostOrComment,
|
||||
fetcher::PostOrComment,
|
||||
mentions::MentionOrValue,
|
||||
objects::{comment::ApubComment, community::ApubCommunity, person::ApubPerson, post::ApubPost},
|
||||
protocol::{
|
||||
|
@ -77,8 +77,8 @@ impl Note {
|
|||
}
|
||||
let parent = self.in_reply_to.dereference(context).await?;
|
||||
match parent {
|
||||
PostOrComment::Post(p) => Ok((p.clone(), None)),
|
||||
PostOrComment::Comment(c) => {
|
||||
PostOrComment::Left(p) => Ok((p.clone(), None)),
|
||||
PostOrComment::Right(c) => {
|
||||
let post_id = c.post_id;
|
||||
let post = Post::read(&mut context.pool(), post_id).await?;
|
||||
Ok((post.into(), Some(c.clone())))
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
use crate::{
|
||||
fetcher::user_or_community::PersonOrGroupType,
|
||||
objects::{community::ApubCommunity, person::ApubPerson, post::ApubPost},
|
||||
protocol::{
|
||||
objects::{AttributedTo, LanguageTag},
|
||||
objects::{AttributedTo, LanguageTag, PersonOrGroupType},
|
||||
ImageObject,
|
||||
InCommunity,
|
||||
Source,
|
||||
|
|
|
@ -3,7 +3,7 @@ use diesel::prelude::*;
|
|||
use diesel_async::RunQueryDsl;
|
||||
use lemmy_apub::{
|
||||
activity_lists::SharedInboxActivities,
|
||||
fetcher::{site_or_community_or_user::SiteOrCommunityOrUser, user_or_community::UserOrCommunity},
|
||||
fetcher::{SiteOrCommunityOrUser, UserOrCommunity},
|
||||
};
|
||||
use lemmy_db_schema::{
|
||||
newtypes::ActivityId,
|
||||
|
@ -144,19 +144,19 @@ pub(crate) async fn get_actor_cached(
|
|||
.try_get_with(actor_apub_id.clone(), async {
|
||||
let url = actor_apub_id.clone().into();
|
||||
let person = match actor_type {
|
||||
ActorType::Site => SiteOrCommunityOrUser::Site(
|
||||
ActorType::Site => SiteOrCommunityOrUser::Left(
|
||||
Site::read_from_apub_id(pool, &url)
|
||||
.await?
|
||||
.context("apub site not found")?
|
||||
.into(),
|
||||
),
|
||||
ActorType::Community => SiteOrCommunityOrUser::UserOrCommunity(UserOrCommunity::Community(
|
||||
ActorType::Community => SiteOrCommunityOrUser::Right(UserOrCommunity::Right(
|
||||
Community::read_from_apub_id(pool, &url)
|
||||
.await?
|
||||
.context("apub community not found")?
|
||||
.into(),
|
||||
)),
|
||||
ActorType::Person => SiteOrCommunityOrUser::UserOrCommunity(UserOrCommunity::User(
|
||||
ActorType::Person => SiteOrCommunityOrUser::Right(UserOrCommunity::Left(
|
||||
Person::read_from_apub_id(pool, &url)
|
||||
.await?
|
||||
.context("apub person not found")?
|
||||
|
|
Loading…
Reference in a new issue