feat: improved address expanding
should now expand non-canonical followers too (aka followers urls not ending with /followers), and also audience! (but im doing audience expansion only for objects rn, not activities)
This commit is contained in:
parent
e7e8653ce2
commit
e300c31488
1 changed files with 30 additions and 30 deletions
|
@ -1,7 +1,7 @@
|
||||||
use std::collections::BTreeSet;
|
use std::collections::BTreeSet;
|
||||||
|
|
||||||
use apb::target::Addressed;
|
use apb::target::Addressed;
|
||||||
use sea_orm::{ActiveValue::{NotSet, Set}, ConnectionTrait, DbErr, EntityTrait, QuerySelect, SelectColumns};
|
use sea_orm::{ActiveValue::{NotSet, Set}, ColumnTrait, ConnectionTrait, DbErr, EntityTrait, QueryFilter, QuerySelect, SelectColumns};
|
||||||
|
|
||||||
use crate::traits::fetch::Fetcher;
|
use crate::traits::fetch::Fetcher;
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ pub trait Addresser {
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl Addresser for crate::Context {
|
impl Addresser for crate::Context {
|
||||||
async fn deliver(&self, to: Vec<String>, aid: &str, from: &str, tx: &impl ConnectionTrait) -> Result<(), DbErr> {
|
async fn deliver(&self, to: Vec<String>, aid: &str, from: &str, tx: &impl ConnectionTrait) -> Result<(), DbErr> {
|
||||||
let to = expand_addressing(to, tx).await?;
|
let to = expand_addressing(to, None, tx).await?;
|
||||||
let mut deliveries = Vec::new();
|
let mut deliveries = Vec::new();
|
||||||
for target in to.into_iter()
|
for target in to.into_iter()
|
||||||
.filter(|to| !to.is_empty())
|
.filter(|to| !to.is_empty())
|
||||||
|
@ -60,16 +60,16 @@ impl Addresser for crate::Context {
|
||||||
match (activity, object) {
|
match (activity, object) {
|
||||||
(None, None) => Ok(()),
|
(None, None) => Ok(()),
|
||||||
(Some(activity), None) => {
|
(Some(activity), None) => {
|
||||||
let to = expand_addressing(activity.addressed(), tx).await?;
|
let to = expand_addressing(activity.addressed(), None, tx).await?;
|
||||||
address_to(self, to, Some(activity.internal), None, self.is_local(&activity.id), activity.published, tx).await
|
address_to(self, to, Some(activity.internal), None, self.is_local(&activity.id), activity.published, tx).await
|
||||||
},
|
},
|
||||||
(None, Some(object)) => {
|
(None, Some(object)) => {
|
||||||
let to = expand_addressing(object.addressed(), tx).await?;
|
let to = expand_addressing(object.addressed(), object.audience.clone(), tx).await?;
|
||||||
address_to(self, to, None, Some(object.internal), self.is_local(&object.id), object.published, tx).await
|
address_to(self, to, None, Some(object.internal), self.is_local(&object.id), object.published, tx).await
|
||||||
},
|
},
|
||||||
(Some(activity), Some(object)) => {
|
(Some(activity), Some(object)) => {
|
||||||
let to_activity = BTreeSet::from_iter(expand_addressing(activity.addressed(), tx).await?);
|
let to_activity = BTreeSet::from_iter(expand_addressing(activity.addressed(), None, tx).await?);
|
||||||
let to_object = BTreeSet::from_iter(expand_addressing(object.addressed(), tx).await?);
|
let to_object = BTreeSet::from_iter(expand_addressing(object.addressed(), object.audience.clone(), tx).await?);
|
||||||
let to_common = to_activity.intersection(&to_object).cloned().collect();
|
let to_common = to_activity.intersection(&to_object).cloned().collect();
|
||||||
address_to(self, to_common, Some(activity.internal), Some(object.internal), self.is_local(&activity.id), activity.published, tx).await?;
|
address_to(self, to_common, Some(activity.internal), Some(object.internal), self.is_local(&activity.id), activity.published, tx).await?;
|
||||||
let to_only_activity = (&to_activity - &to_object).into_iter().collect();
|
let to_only_activity = (&to_activity - &to_object).into_iter().collect();
|
||||||
|
@ -122,36 +122,36 @@ async fn address_to(ctx: &crate::Context, to: Vec<String>, aid: Option<i64>, oid
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn expand_addressing(targets: Vec<String>, tx: &impl ConnectionTrait) -> Result<Vec<String>, DbErr> {
|
async fn expand_addressing(targets: Vec<String>, audience: Option<String>, tx: &impl ConnectionTrait) -> Result<Vec<String>, DbErr> {
|
||||||
let mut out = Vec::new();
|
let mut out = Vec::new();
|
||||||
for target in targets {
|
if let Some(audience) = audience {
|
||||||
// TODO this is definitely NOT a reliable way to expand followers collections...
|
if let Some(internal) = crate::model::actor::Entity::ap_to_internal(&audience, tx).await? {
|
||||||
// we should add an index on following field in users and try to search for that: no
|
let mut members = crate::Query::related(None, Some(internal), false)
|
||||||
// guarantee that all followers collections end with 'followers'! once we get the actual
|
|
||||||
// user we can resolve their followers with the relations table
|
|
||||||
// ! NOTE THAT local users have followers set to NULL, either fill all local users followers
|
|
||||||
// field or manually check if it's local and then do the .ends_with("/followers")
|
|
||||||
// TODO should also expand /following
|
|
||||||
// TODO should probably expand audience too but it's not reachable anymore from here, should we
|
|
||||||
// count audience field too in the .addressed() trait? maybe pre-expand it because it's
|
|
||||||
// only used for groups anyway??
|
|
||||||
if target.ends_with("/followers") {
|
|
||||||
let target_id = target.replace("/followers", "");
|
|
||||||
let target_internal = crate::model::actor::Entity::ap_to_internal(&target_id, tx)
|
|
||||||
.await?
|
|
||||||
.ok_or_else(|| DbErr::RecordNotFound(target_id.clone()))?;
|
|
||||||
let mut followers = crate::Query::related(None, Some(target_internal), false)
|
|
||||||
.select_only()
|
.select_only()
|
||||||
.select_column(crate::model::actor::Column::Id)
|
.select_column(crate::model::actor::Column::Id)
|
||||||
.into_tuple::<String>()
|
.into_tuple::<String>()
|
||||||
.all(tx)
|
.all(tx)
|
||||||
.await?;
|
.await?;
|
||||||
if followers.is_empty() { // stuff with zero addressing will never be seen again!!! TODO
|
out.append(&mut members);
|
||||||
followers.push(target_id);
|
|
||||||
}
|
}
|
||||||
for follower in followers {
|
|
||||||
out.push(follower);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for target in targets {
|
||||||
|
if let Some(followers_of) = crate::model::actor::Entity::find()
|
||||||
|
.filter(crate::model::actor::Column::Followers.eq(&target))
|
||||||
|
.select_only()
|
||||||
|
.select_column(crate::model::actor::Column::Internal)
|
||||||
|
.into_tuple::<i64>()
|
||||||
|
.one(tx)
|
||||||
|
.await?
|
||||||
|
{
|
||||||
|
let mut followers = crate::Query::related(None, Some(followers_of), false)
|
||||||
|
.select_only()
|
||||||
|
.select_column(crate::model::actor::Column::Id)
|
||||||
|
.into_tuple::<String>()
|
||||||
|
.all(tx)
|
||||||
|
.await?;
|
||||||
|
out.append(&mut followers);
|
||||||
} else {
|
} else {
|
||||||
out.push(target);
|
out.push(target);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue