feat: process and store fields and aliases

basically moved_to, also_known_as and actor attachments
This commit is contained in:
əlemi 2024-07-15 13:57:03 +02:00
parent f115ab67b8
commit e0f427a2b9
Signed by: alemi
GPG key ID: A4895B84D311642C
6 changed files with 81 additions and 2 deletions

View file

@ -34,6 +34,6 @@ tracing = "0.1"
tokio = { version = "1.35", features = ["full"] } # TODO slim this down
sea-orm = { version = "0.12", features = ["macros", "sqlx-sqlite", "sqlx-postgres", "runtime-tokio-rustls"] }
reqwest = { version = "0.12", features = ["json"] }
apb = { path = "../../apb", features = ["unstructured", "orm", "activitypub-fe", "activitypub-counters", "litepub", "ostatus", "toot"] }
apb = { path = "../../apb", features = ["unstructured", "orm", "did-core", "activitypub-miscellaneous-terms", "activitypub-fe", "activitypub-counters", "litepub", "ostatus", "toot"] }
# nodeinfo = "0.0.2" # the version on crates.io doesn't re-export necessary types to build the struct!!!
nodeinfo = { git = "https://codeberg.org/thefederationinfo/nodeinfo-rs", rev = "e865094804" }

View file

@ -1,6 +1,27 @@
use sea_orm::{entity::prelude::*, QuerySelect, SelectColumns};
use apb::{ActorMut, ActorType, BaseMut, DocumentMut, EndpointsMut, ObjectMut, PublicKeyMut};
use apb::{field::OptionalString, ActorMut, ActorType, BaseMut, DocumentMut, EndpointsMut, ObjectMut, PublicKeyMut};
#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize, sea_orm::FromJsonQueryResult)]
pub struct Field {
pub name: String,
pub content: String,
pub verified_at: Option<ChronoDateTimeUtc>,
#[serde(rename = "type")]
pub field_type: String,
}
impl<T: apb::Object> From<T> for Field {
fn from(value: T) -> Self {
Field {
name: value.name().str().unwrap_or_default(),
content: value.content().str().unwrap_or_default(),
field_type: "PropertyValue".to_string(), // TODO can we try parsing this instead??
verified_at: None, // TODO where does verified_at come from? extend apb maybe
}
}
}
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
#[sea_orm(table_name = "actors")]
@ -16,6 +37,7 @@ pub struct Model {
pub image: Option<String>,
pub icon: Option<String>,
pub preferred_username: String,
pub fields: Vec<Field>,
pub inbox: Option<String>,
pub shared_inbox: Option<String>,
pub outbox: Option<String>,
@ -28,6 +50,8 @@ pub struct Model {
pub private_key: Option<String>,
pub published: ChronoDateTimeUtc,
pub updated: ChronoDateTimeUtc,
pub also_known_as: Vec<String>,
pub moved_to: Option<String>,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
@ -183,6 +207,12 @@ impl Model {
.set_document_type(Some(apb::DocumentType::Image))
.set_url(apb::Node::link(i.clone()))
)))
.set_attachment(apb::Node::array(
self.fields
.into_iter()
.filter_map(|x| serde_json::to_value(&x).ok())
.collect()
))
.set_published(Some(self.published))
.set_updated(if self.updated != self.published { Some(self.updated) } else { None })
.set_preferred_username(Some(&self.preferred_username))
@ -203,6 +233,8 @@ impl Model {
apb::new()
.set_shared_inbox(self.shared_inbox.as_deref())
))
.set_also_known_as(apb::Node::links(self.also_known_as))
.set_moved_to(apb::Node::maybe_link(self.moved_to))
.set_discoverable(Some(true))
}
}

View file

@ -333,11 +333,14 @@ impl AP {
summary: actor.summary().str(),
icon: actor.icon().get().and_then(|x| x.url().id().str()),
image: actor.image().get().and_then(|x| x.url().id().str()),
fields: actor.attachment().flat().into_iter().filter_map(|x| Some(crate::model::actor::Field::from(x.extract()?))).collect(),
inbox: actor.inbox().id().str(),
outbox: actor.outbox().id().str(),
shared_inbox: actor.endpoints().get().and_then(|x| x.shared_inbox().str()),
followers: actor.followers().id().str(),
following: actor.following().id().str(),
also_known_as: actor.also_known_as().flat().into_iter().filter_map(|x| x.id().str()).collect(),
moved_to: actor.moved_to().id().str(),
published: actor.published().unwrap_or(chrono::Utc::now()),
updated: chrono::Utc::now(),
following_count: actor.following_count().unwrap_or(0) as i32,

View file

@ -18,6 +18,7 @@ mod m20240703_000001_add_audience_index;
mod m20240703_000002_add_image_to_objects;
mod m20240706_000001_add_error_to_jobs;
mod m20240715_000001_add_quote_uri_to_objects;
mod m20240715_000002_add_actors_fields_and_aliases;
pub struct Migrator;
@ -43,6 +44,7 @@ impl MigratorTrait for Migrator {
Box::new(m20240703_000002_add_image_to_objects::Migration),
Box::new(m20240706_000001_add_error_to_jobs::Migration),
Box::new(m20240715_000001_add_quote_uri_to_objects::Migration),
Box::new(m20240715_000002_add_actors_fields_and_aliases::Migration),
]
}
}

View file

@ -12,6 +12,7 @@ pub enum Actors {
Image,
Icon,
PreferredUsername,
Fields, // added with migration m20240715_000002
Inbox,
SharedInbox,
Outbox,
@ -22,6 +23,8 @@ pub enum Actors {
StatusesCount,
PublicKey,
PrivateKey,
AlsoKnownAs, // added with migration m20240715_000002
MovedTo, // added with migration m20240715_000002
Published,
Updated,
}

View file

@ -0,0 +1,39 @@
use sea_orm_migration::prelude::*;
use crate::m20240524_000001_create_actor_activity_object_tables::Actors;
#[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(Actors::Table)
.add_column(ColumnDef::new(Actors::MovedTo).string().null())
.add_column(ColumnDef::new(Actors::AlsoKnownAs).json_binary().not_null().default::<Vec<String>>(vec![]))
.add_column(ColumnDef::new(Actors::Fields).json_binary().not_null().default::<Vec<String>>(vec![]))
.to_owned()
)
.await?;
Ok(())
}
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager
.alter_table(
Table::alter()
.table(Actors::Table)
.drop_column(Actors::MovedTo)
.drop_column(Actors::AlsoKnownAs)
.drop_column(Actors::Fields)
.to_owned()
)
.await?;
Ok(())
}
}