forked from alemi/upub
feat: add instance id in relations
this is needed to provide instance-scoped relations
This commit is contained in:
parent
846d0f21d5
commit
129724d30e
5 changed files with 142 additions and 7 deletions
|
@ -9,6 +9,8 @@ pub struct Model {
|
|||
pub following: i64,
|
||||
pub accept: Option<i64>,
|
||||
pub activity: i64,
|
||||
pub follower_instance: i64,
|
||||
pub following_instance: i64,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||
|
@ -45,6 +47,22 @@ pub enum Relation {
|
|||
on_delete = "Cascade"
|
||||
)]
|
||||
ActorsFollowing,
|
||||
#[sea_orm(
|
||||
belongs_to = "super::instance::Entity",
|
||||
from = "Column::FollowerInstance",
|
||||
to = "super::instance::Column::Internal",
|
||||
on_update = "Cascade",
|
||||
on_delete = "NoAction"
|
||||
)]
|
||||
InstancesFollower,
|
||||
#[sea_orm(
|
||||
belongs_to = "super::instance::Entity",
|
||||
from = "Column::FollowingInstance",
|
||||
to = "super::instance::Column::Internal",
|
||||
on_update = "Cascade",
|
||||
on_delete = "NoAction"
|
||||
)]
|
||||
InstancesFollowing,
|
||||
}
|
||||
|
||||
impl Related<super::actor::Entity> for Entity {
|
||||
|
@ -59,6 +77,12 @@ impl Related<super::activity::Entity> for Entity {
|
|||
}
|
||||
}
|
||||
|
||||
impl Related<super::instance::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::InstancesFollowing.def()
|
||||
}
|
||||
}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
||||
|
||||
impl Entity {
|
||||
|
|
|
@ -116,15 +116,16 @@ pub async fn like(ctx: &crate::Context, activity: impl apb::Activity, tx: &Datab
|
|||
}
|
||||
|
||||
pub async fn follow(ctx: &crate::Context, activity: impl apb::Activity, tx: &DatabaseTransaction) -> Result<(), ProcessorError> {
|
||||
let source_actor_internal = crate::model::actor::Entity::ap_to_internal(activity.actor().id()?, tx)
|
||||
let source_actor = crate::model::actor::Entity::find_by_ap_id(activity.actor().id()?)
|
||||
.one(tx)
|
||||
.await?
|
||||
.ok_or(ProcessorError::Incomplete)?;
|
||||
let usr = ctx.fetch_user(activity.object().id()?, tx).await?;
|
||||
let target_actor = ctx.fetch_user(activity.object().id()?, tx).await?;
|
||||
let activity_model = ctx.insert_activity(activity, tx).await?;
|
||||
|
||||
if let Some(relation) = crate::model::relation::Entity::find()
|
||||
.filter(crate::model::relation::Column::Follower.eq(source_actor_internal))
|
||||
.filter(crate::model::relation::Column::Following.eq(usr.internal))
|
||||
.filter(crate::model::relation::Column::Follower.eq(source_actor.internal))
|
||||
.filter(crate::model::relation::Column::Following.eq(target_actor.internal))
|
||||
.select_only()
|
||||
.select_column(crate::model::relation::Column::Internal)
|
||||
.into_tuple::<i64>()
|
||||
|
@ -140,19 +141,29 @@ pub async fn follow(ctx: &crate::Context, activity: impl apb::Activity, tx: &Dat
|
|||
|
||||
} else {
|
||||
|
||||
let follower_instance = crate::model::instance::Entity::domain_to_internal(&source_actor.domain, tx)
|
||||
.await?
|
||||
.ok_or(ProcessorError::Incomplete)?;
|
||||
|
||||
let following_instance = crate::model::instance::Entity::domain_to_internal(&target_actor.domain, tx)
|
||||
.await?
|
||||
.ok_or(ProcessorError::Incomplete)?;
|
||||
|
||||
// new follow request, make new row
|
||||
let relation_model = crate::model::relation::ActiveModel {
|
||||
internal: NotSet,
|
||||
accept: Set(None),
|
||||
activity: Set(activity_model.internal),
|
||||
follower: Set(source_actor_internal),
|
||||
following: Set(usr.internal),
|
||||
follower: Set(source_actor.internal),
|
||||
follower_instance: Set(follower_instance),
|
||||
following: Set(target_actor.internal),
|
||||
following_instance: Set(following_instance),
|
||||
};
|
||||
crate::model::relation::Entity::insert(relation_model)
|
||||
.exec(tx).await?;
|
||||
}
|
||||
|
||||
tracing::info!("{} wants to follow {}", activity_model.actor, usr.id);
|
||||
tracing::info!("{} wants to follow {}", activity_model.actor, target_actor.id);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ mod m20240529_000001_add_relation_unique_index;
|
|||
mod m20240605_000001_add_jobs_table;
|
||||
mod m20240606_000001_add_audience_to_objects;
|
||||
mod m20240607_000001_activity_ref_is_optional;
|
||||
mod m20240609_000001_add_instance_field_to_relations;
|
||||
|
||||
pub struct Migrator;
|
||||
|
||||
|
@ -25,6 +26,7 @@ impl MigratorTrait for Migrator {
|
|||
Box::new(m20240605_000001_add_jobs_table::Migration),
|
||||
Box::new(m20240606_000001_add_audience_to_objects::Migration),
|
||||
Box::new(m20240607_000001_activity_ref_is_optional::Migration),
|
||||
Box::new(m20240609_000001_add_instance_field_to_relations::Migration),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,8 @@ pub enum Relations {
|
|||
Following,
|
||||
Activity,
|
||||
Accept,
|
||||
FollowerInstance, // ADDED AFTERWARDS
|
||||
FollowingInstance, // ADDED AFTERWARDS
|
||||
}
|
||||
|
||||
#[derive(DeriveIden)]
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
use sea_orm_migration::prelude::*;
|
||||
|
||||
use crate::{m20240524_000001_create_actor_activity_object_tables::Instances, m20240524_000002_create_relations_likes_shares::Relations};
|
||||
|
||||
#[derive(DeriveMigrationName)]
|
||||
pub struct Migration;
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
|
||||
manager
|
||||
.alter_table(
|
||||
Table::alter()
|
||||
.table(Relations::Table)
|
||||
.add_column(ColumnDef::new(Relations::FollowerInstance).big_integer().not_null())
|
||||
.add_foreign_key(
|
||||
TableForeignKey::new()
|
||||
.name("fkey-relations-follower-instance")
|
||||
.from_tbl(Relations::Table)
|
||||
.from_col(Relations::FollowerInstance)
|
||||
.to_tbl(Instances::Table)
|
||||
.to_col(Instances::Internal)
|
||||
.on_update(ForeignKeyAction::Cascade)
|
||||
)
|
||||
.add_column(ColumnDef::new(Relations::FollowingInstance).big_integer().not_null())
|
||||
.add_foreign_key(
|
||||
TableForeignKey::new()
|
||||
.name("fkey-relations-following-instance")
|
||||
.from_tbl(Relations::Table)
|
||||
.from_col(Relations::FollowingInstance)
|
||||
.to_tbl(Instances::Table)
|
||||
.to_col(Instances::Internal)
|
||||
.on_update(ForeignKeyAction::Cascade)
|
||||
)
|
||||
.to_owned()
|
||||
)
|
||||
.await?;
|
||||
|
||||
manager
|
||||
.create_index(
|
||||
Index::create()
|
||||
.name("index-relations-follower-instance")
|
||||
.table(Relations::Table)
|
||||
.col(Relations::FollowerInstance)
|
||||
.to_owned()
|
||||
).await?;
|
||||
|
||||
manager
|
||||
.create_index(
|
||||
Index::create()
|
||||
.name("index-relations-following-instance")
|
||||
.table(Relations::Table)
|
||||
.col(Relations::FollowingInstance)
|
||||
.to_owned()
|
||||
).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
|
||||
manager
|
||||
.drop_index(
|
||||
Index::drop()
|
||||
.name("index-relations-follower-instance")
|
||||
.table(Relations::Table)
|
||||
.to_owned()
|
||||
)
|
||||
.await?;
|
||||
|
||||
manager
|
||||
.drop_index(
|
||||
Index::drop()
|
||||
.name("index-relations-following-instance")
|
||||
.table(Relations::Table)
|
||||
.to_owned()
|
||||
)
|
||||
.await?;
|
||||
|
||||
manager
|
||||
.alter_table(
|
||||
Table::alter()
|
||||
.table(Relations::Table)
|
||||
.drop_foreign_key(Alias::new("fkey-relations-follower-instance"))
|
||||
.drop_column(Relations::FollowerInstance)
|
||||
.drop_foreign_key(Alias::new("fkey-relations-following-instance"))
|
||||
.drop_column(Relations::FollowingInstance)
|
||||
.to_owned()
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in a new issue