1
0
Fork 0
forked from alemi/upub

feat: updated entities

i think it's all of them? constructors are still weird
This commit is contained in:
əlemi 2024-05-24 05:05:14 +02:00
parent 749dcc1ae7
commit 12c5a6f3a5
Signed by: alemi
GPG key ID: A4895B84D311642C
18 changed files with 678 additions and 421 deletions

View file

@ -1,46 +1,95 @@
use apb::{ActivityMut, BaseMut, ObjectMut}; use apb::{ActivityMut, ActivityType, BaseMut, ObjectMut};
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use crate::routes::activitypub::jsonld::LD; use crate::routes::activitypub::jsonld::LD;
use super::Audience;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
#[sea_orm(table_name = "activities")] #[sea_orm(table_name = "activities")]
pub struct Model { pub struct Model {
#[sea_orm(primary_key)] #[sea_orm(primary_key)]
pub id: String, pub id: i32,
#[sea_orm(unique)]
pub activity_type: apb::ActivityType, pub ap_id: String,
pub actor: String, pub activity_type: ActivityType,
pub object: Option<String>, pub actor: i32,
pub object: Option<i32>,
pub target: Option<String>, // TODO relates to USER maybe?? pub target: Option<String>,
pub cc: Audience, pub to: Option<Json>,
pub bcc: Audience, pub bto: Option<Json>,
pub to: Audience, pub cc: Option<Json>,
pub bto: Audience, pub bcc: Option<Json>,
pub published: ChronoDateTimeUtc, pub published: ChronoDateTimeUtc,
}
// TODO: origin, result, instrument #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::actor::Entity",
from = "Column::Actor",
to = "super::actor::Column::Id",
on_update = "Cascade",
on_delete = "NoAction"
)]
Actors,
#[sea_orm(has_many = "super::addressing::Entity")]
Addressing,
#[sea_orm(has_many = "super::delivery::Entity")]
Deliveries,
#[sea_orm(
belongs_to = "super::object::Entity",
from = "Column::Object",
to = "super::object::Column::Id",
on_update = "Cascade",
on_delete = "NoAction"
)]
Objects,
}
impl Related<super::actor::Entity> for Entity {
fn to() -> RelationDef {
Relation::Actors.def()
}
}
impl Related<super::addressing::Entity> for Entity {
fn to() -> RelationDef {
Relation::Addressing.def()
}
}
impl Related<super::delivery::Entity> for Entity {
fn to() -> RelationDef {
Relation::Deliveries.def()
}
}
impl Related<super::object::Entity> for Entity {
fn to() -> RelationDef {
Relation::Objects.def()
}
}
impl ActiveModelBehavior for ActiveModel {}
impl ActiveModel {
pub fn new(activity: &impl apb::Activity) -> Result<Self, super::FieldError> {
Ok(ActiveModel {
id: sea_orm::ActiveValue::NotSet,
ap_id: sea_orm::ActiveValue::Set(activity.id().ok_or(super::FieldError("id"))?.to_string()),
activity_type: sea_orm::ActiveValue::Set(activity.activity_type().ok_or(super::FieldError("type"))?),
actor: sea_orm::ActiveValue::Set(activity.actor().id().ok_or(super::FieldError("actor"))?),
object: sea_orm::ActiveValue::Set(activity.object().id()),
target: sea_orm::ActiveValue::Set(activity.target().id()),
published: sea_orm::ActiveValue::Set(activity.published().unwrap_or(chrono::Utc::now())),
to: sea_orm::ActiveValue::Set(activity.to().into()),
bto: sea_orm::ActiveValue::Set(activity.bto().into()),
cc: sea_orm::ActiveValue::Set(activity.cc().into()),
bcc: sea_orm::ActiveValue::Set(activity.bcc().into()),
})
}
} }
impl Model { impl Model {
pub fn new(activity: &impl apb::Activity) -> Result<Self, super::FieldError> {
Ok(Model {
id: activity.id().ok_or(super::FieldError("id"))?.to_string(),
activity_type: activity.activity_type().ok_or(super::FieldError("type"))?,
actor: activity.actor().id().ok_or(super::FieldError("actor"))?,
object: activity.object().id(),
target: activity.target().id(),
published: activity.published().unwrap_or(chrono::Utc::now()),
to: activity.to().into(),
bto: activity.bto().into(),
cc: activity.cc().into(),
bcc: activity.bcc().into(),
})
}
pub fn ap(self) -> serde_json::Value { pub fn ap(self) -> serde_json::Value {
serde_json::Value::new_object() serde_json::Value::new_object()
.set_id(Some(&self.id)) .set_id(Some(&self.id))
@ -56,49 +105,6 @@ impl Model {
} }
} }
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::Actor",
to = "super::user::Column::Id"
)]
User,
#[sea_orm(
belongs_to = "super::object::Entity",
from = "Column::Object",
to = "super::object::Column::Id"
)]
Object,
#[sea_orm(has_many = "super::addressing::Entity")]
Addressing,
#[sea_orm(has_many = "super::delivery::Entity")]
Delivery,
}
impl Related<super::user::Entity> for Entity {
fn to() -> RelationDef {
Relation::User.def()
}
}
impl Related<super::object::Entity> for Entity {
fn to() -> RelationDef {
Relation::Object.def()
}
}
impl Related<super::addressing::Entity> for Entity {
fn to() -> RelationDef {
Relation::Addressing.def()
}
}
impl ActiveModelBehavior for ActiveModel {}
impl apb::target::Addressed for Model { impl apb::target::Addressed for Model {
fn addressed(&self) -> Vec<String> { fn addressed(&self) -> Vec<String> {
let mut to : Vec<String> = self.to.0.clone(); let mut to : Vec<String> = self.to.0.clone();

View file

@ -5,68 +5,165 @@ use apb::{Actor, ActorMut, ActorType, BaseMut, DocumentMut, Endpoints, Endpoints
use crate::routes::activitypub::jsonld::LD; use crate::routes::activitypub::jsonld::LD;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
#[sea_orm(table_name = "users")] #[sea_orm(table_name = "actors")]
pub struct Model { pub struct Model {
#[sea_orm(primary_key)] #[sea_orm(primary_key)]
pub id: String, pub id: i32,
pub domain: String, #[sea_orm(unique)]
pub ap_id: String,
pub actor_type: ActorType, pub actor_type: ActorType,
pub preferred_username: String, pub instance: i32,
pub name: Option<String>, pub name: Option<String>,
pub summary: Option<String>, pub summary: Option<String>,
pub image: Option<String>, pub image: Option<String>,
pub icon: Option<String>, pub icon: Option<String>,
#[sea_orm(unique)]
pub preferred_username: String,
pub inbox: Option<String>, pub inbox: Option<String>,
pub shared_inbox: Option<String>, pub shared_inbox: Option<String>,
pub outbox: Option<String>, pub outbox: Option<String>,
pub following: Option<String>, pub following: Option<String>,
pub followers: Option<String>, pub followers: Option<String>,
pub following_count: i32,
pub following_count: i64, pub followers_count: i32,
pub followers_count: i64, pub statuses_count: i32,
pub statuses_count: i64,
pub public_key: String, pub public_key: String,
pub private_key: Option<String>, pub private_key: Option<String>,
pub created: ChronoDateTimeUtc, pub created: ChronoDateTimeUtc,
pub updated: ChronoDateTimeUtc, pub updated: ChronoDateTimeUtc,
}
// TODO these are also suggested
// pub liked: Option<String>, #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
// pub streams: Option<String>, pub enum Relation {
#[sea_orm(has_many = "super::activity::Entity")]
Activities,
#[sea_orm(has_many = "super::addressing::Entity")]
Addressing,
#[sea_orm(has_many = "super::announce::Entity")]
Announces,
#[sea_orm(has_many = "super::config::Entity")]
Configs,
#[sea_orm(has_many = "super::credential::Entity")]
Credentials,
#[sea_orm(has_many = "super::delivery::Entity")]
Deliveries,
#[sea_orm(
belongs_to = "super::instance::Entity",
from = "Column::Instance",
to = "super::instance::Column::Id",
on_update = "Cascade",
on_delete = "NoAction"
)]
Instances,
#[sea_orm(has_many = "super::like::Entity")]
Likes,
#[sea_orm(has_many = "super::mention::Entity")]
Mentions,
#[sea_orm(has_many = "super::object::Entity")]
Objects,
#[sea_orm(has_many = "super::session::Entity")]
Sessions,
}
impl Related<super::activity::Entity> for Entity {
fn to() -> RelationDef {
Relation::Activities.def()
}
}
impl Related<super::addressing::Entity> for Entity {
fn to() -> RelationDef {
Relation::Addressing.def()
}
}
impl Related<super::announce::Entity> for Entity {
fn to() -> RelationDef {
Relation::Announces.def()
}
}
impl Related<super::config::Entity> for Entity {
fn to() -> RelationDef {
Relation::Configs.def()
}
}
impl Related<super::credential::Entity> for Entity {
fn to() -> RelationDef {
Relation::Credentials.def()
}
}
impl Related<super::delivery::Entity> for Entity {
fn to() -> RelationDef {
Relation::Deliveries.def()
}
}
impl Related<super::instance::Entity> for Entity {
fn to() -> RelationDef {
Relation::Instances.def()
}
}
impl Related<super::like::Entity> for Entity {
fn to() -> RelationDef {
Relation::Likes.def()
}
}
impl Related<super::mention::Entity> for Entity {
fn to() -> RelationDef {
Relation::Mentions.def()
}
}
impl Related<super::object::Entity> for Entity {
fn to() -> RelationDef {
Relation::Objects.def()
}
}
impl Related<super::session::Entity> for Entity {
fn to() -> RelationDef {
Relation::Sessions.def()
}
}
impl ActiveModelBehavior for ActiveModel {}
impl ActiveModel {
pub fn new(object: &impl Actor, instance: i32) -> Result<Self, super::FieldError> {
let ap_id = object.id().ok_or(super::FieldError("id"))?.to_string();
let (_domain, fallback_preferred_username) = split_user_id(&ap_id);
Ok(ActiveModel {
instance: sea_orm::ActiveValue::Set(instance), // TODO receiving it from outside is cheap
id: sea_orm::ActiveValue::NotSet,
ap_id: sea_orm::ActiveValue::Set(ap_id),
preferred_username: sea_orm::ActiveValue::Set(object.preferred_username().unwrap_or(&fallback_preferred_username).to_string()),
actor_type: sea_orm::ActiveValue::Set(object.actor_type().ok_or(super::FieldError("type"))?),
name: sea_orm::ActiveValue::Set(object.name().map(|x| x.to_string())),
summary: sea_orm::ActiveValue::Set(object.summary().map(|x| x.to_string())),
icon: sea_orm::ActiveValue::Set(object.icon().get().and_then(|x| x.url().id())),
image: sea_orm::ActiveValue::Set(object.image().get().and_then(|x| x.url().id())),
inbox: sea_orm::ActiveValue::Set(object.inbox().id()),
outbox: sea_orm::ActiveValue::Set(object.outbox().id()),
shared_inbox: sea_orm::ActiveValue::Set(object.endpoints().get().and_then(|x| Some(x.shared_inbox()?.to_string()))),
followers: sea_orm::ActiveValue::Set(object.followers().id()),
following: sea_orm::ActiveValue::Set(object.following().id()),
created: sea_orm::ActiveValue::Set(object.published().unwrap_or(chrono::Utc::now())),
updated: sea_orm::ActiveValue::Set(chrono::Utc::now()),
following_count: sea_orm::ActiveValue::Set(object.following_count().unwrap_or(0) as i64),
followers_count: sea_orm::ActiveValue::Set(object.followers_count().unwrap_or(0) as i64),
statuses_count: sea_orm::ActiveValue::Set(object.statuses_count().unwrap_or(0) as i64),
public_key: sea_orm::ActiveValue::Set(object.public_key().get().ok_or(super::FieldError("publicKey"))?.public_key_pem().to_string()),
private_key: sea_orm::ActiveValue::Set(None), // there's no way to transport privkey over AP json, must come from DB
})
}
} }
impl Model { impl Model {
pub fn new(object: &impl Actor) -> Result<Self, super::FieldError> {
let ap_id = object.id().ok_or(super::FieldError("id"))?.to_string();
let (domain, fallback_preferred_username) = split_user_id(&ap_id);
Ok(Model {
id: ap_id,
domain,
preferred_username: object.preferred_username().unwrap_or(&fallback_preferred_username).to_string(),
actor_type: object.actor_type().ok_or(super::FieldError("type"))?,
name: object.name().map(|x| x.to_string()),
summary: object.summary().map(|x| x.to_string()),
icon: object.icon().get().and_then(|x| x.url().id()),
image: object.image().get().and_then(|x| x.url().id()),
inbox: object.inbox().id(),
outbox: object.outbox().id(),
shared_inbox: object.endpoints().get().and_then(|x| Some(x.shared_inbox()?.to_string())),
followers: object.followers().id(),
following: object.following().id(),
created: object.published().unwrap_or(chrono::Utc::now()),
updated: chrono::Utc::now(),
following_count: object.following_count().unwrap_or(0) as i64,
followers_count: object.followers_count().unwrap_or(0) as i64,
statuses_count: object.statuses_count().unwrap_or(0) as i64,
public_key: object.public_key().get().ok_or(super::FieldError("publicKey"))?.public_key_pem().to_string(),
private_key: None, // there's no way to transport privkey over AP json, must come from DB
})
}
pub fn ap(self) -> serde_json::Value { pub fn ap(self) -> serde_json::Value {
serde_json::Value::new_object() serde_json::Value::new_object()
.set_id(Some(&self.id)) .set_id(Some(&self.id))
@ -106,65 +203,6 @@ impl Model {
} }
} }
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(has_many = "super::activity::Entity")]
Activity,
#[sea_orm(has_many = "super::object::Entity")]
Object,
#[sea_orm(has_one = "super::config::Entity")]
Config,
#[sea_orm(has_one = "super::credential::Entity")]
Credential,
#[sea_orm(has_many = "super::session::Entity")]
Session,
#[sea_orm(has_many = "super::addressing::Entity")]
Addressing,
}
impl Related<super::activity::Entity> for Entity {
fn to() -> RelationDef {
Relation::Activity.def()
}
}
impl Related<super::object::Entity> for Entity {
fn to() -> RelationDef {
Relation::Object.def()
}
}
impl Related<super::config::Entity> for Entity {
fn to() -> RelationDef {
Relation::Config.def()
}
}
impl Related<super::credential::Entity> for Entity {
fn to() -> RelationDef {
Relation::Credential.def()
}
}
impl Related<super::session::Entity> for Entity {
fn to() -> RelationDef {
Relation::Session.def()
}
}
impl Related<super::addressing::Entity> for Entity {
fn to() -> RelationDef {
Relation::Addressing.def()
}
}
impl ActiveModelBehavior for ActiveModel {}
fn split_user_id(id: &str) -> (String, String) { fn split_user_id(id: &str) -> (String, String) {
let clean = id let clean = id
.replace("http://", "") .replace("http://", "")

View file

@ -7,53 +7,71 @@ use crate::routes::activitypub::jsonld::LD;
#[sea_orm(table_name = "addressing")] #[sea_orm(table_name = "addressing")]
pub struct Model { pub struct Model {
#[sea_orm(primary_key)] #[sea_orm(primary_key)]
pub id: i64, pub id: i32,
pub actor: String, pub actor: i32,
pub server: String, pub instance: i32,
pub activity: Option<String>, pub activity: Option<i32>,
pub object: Option<String>, pub object: Option<i32>,
pub published: ChronoDateTimeUtc, pub published: ChronoDateTimeUtc,
} }
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation { pub enum Relation {
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::Actor",
to = "super::user::Column::Id"
)]
User,
#[sea_orm( #[sea_orm(
belongs_to = "super::activity::Entity", belongs_to = "super::activity::Entity",
from = "Column::Activity", from = "Column::Activity",
to = "super::activity::Column::Id" to = "super::activity::Column::Id",
on_update = "Cascade",
on_delete = "NoAction"
)] )]
Activity, Activities,
#[sea_orm(
belongs_to = "super::actor::Entity",
from = "Column::Actor",
to = "super::actor::Column::Id",
on_update = "Cascade",
on_delete = "NoAction"
)]
Actors,
#[sea_orm(
belongs_to = "super::instance::Entity",
from = "Column::Instance",
to = "super::instance::Column::Id",
on_update = "Cascade",
on_delete = "NoAction"
)]
Instances,
#[sea_orm( #[sea_orm(
belongs_to = "super::object::Entity", belongs_to = "super::object::Entity",
from = "Column::Object", from = "Column::Object",
to = "super::object::Column::Id" to = "super::object::Column::Id",
on_update = "Cascade",
on_delete = "NoAction"
)] )]
Object, Objects,
}
impl Related<super::user::Entity> for Entity {
fn to() -> RelationDef {
Relation::User.def()
}
} }
impl Related<super::activity::Entity> for Entity { impl Related<super::activity::Entity> for Entity {
fn to() -> RelationDef { fn to() -> RelationDef {
Relation::Activity.def() Relation::Activities.def()
}
}
impl Related<super::actor::Entity> for Entity {
fn to() -> RelationDef {
Relation::Actors.def()
}
}
impl Related<super::instance::Entity> for Entity {
fn to() -> RelationDef {
Relation::Instances.def()
} }
} }
impl Related<super::object::Entity> for Entity { impl Related<super::object::Entity> for Entity {
fn to() -> RelationDef { fn to() -> RelationDef {
Relation::Object.def() Relation::Objects.def()
} }
} }

45
src/model/announce.rs Normal file
View file

@ -0,0 +1,45 @@
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
#[sea_orm(table_name = "announces")]
pub struct Model {
#[sea_orm(primary_key)]
pub id: i32,
pub actor: i32,
pub announces: i32,
pub published: ChronoDateTimeUtc,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::actor::Entity",
from = "Column::Actor",
to = "super::actor::Column::Id",
on_update = "Cascade",
on_delete = "Cascade"
)]
Actors,
#[sea_orm(
belongs_to = "super::object::Entity",
from = "Column::Announces",
to = "super::object::Column::Id",
on_update = "Cascade",
on_delete = "Cascade"
)]
Objects,
}
impl Related<super::actor::Entity> for Entity {
fn to() -> RelationDef {
Relation::Actors.def()
}
}
impl Related<super::object::Entity> for Entity {
fn to() -> RelationDef {
Relation::Objects.def()
}
}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -1,18 +0,0 @@
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
#[sea_orm(table_name = "application")]
pub struct Model {
#[sea_orm(primary_key)]
pub id: i64,
pub private_key: String,
pub public_key: String,
pub created: ChronoDateTimeUtc,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -9,16 +9,36 @@ use super::addressing::Event;
#[sea_orm(table_name = "attachments")] #[sea_orm(table_name = "attachments")]
pub struct Model { pub struct Model {
#[sea_orm(primary_key)] #[sea_orm(primary_key)]
pub id: i64, pub id: i32,
#[sea_orm(unique)]
pub url: String, pub url: String,
pub object: String, pub object: i32,
pub document_type: apb::DocumentType, pub document_type: String,
pub name: Option<String>, pub name: Option<String>,
pub media_type: String, pub media_type: String,
pub created: ChronoDateTimeUtc, pub created: ChronoDateTimeUtc,
} }
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::object::Entity",
from = "Column::Object",
to = "super::object::Column::Id",
on_update = "Cascade",
on_delete = "Cascade"
)]
Objects,
}
impl Related<super::object::Entity> for Entity {
fn to() -> RelationDef {
Relation::Objects.def()
}
}
impl ActiveModelBehavior for ActiveModel {}
impl Model { impl Model {
pub fn ap(self) -> serde_json::Value { pub fn ap(self) -> serde_json::Value {
serde_json::Value::new_object() serde_json::Value::new_object()
@ -30,25 +50,6 @@ impl Model {
} }
} }
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::object::Entity",
from = "Column::Object",
to = "super::object::Column::Id"
)]
Object,
}
impl Related<super::object::Entity> for Entity {
fn to() -> RelationDef {
Relation::Object.def()
}
}
impl ActiveModelBehavior for ActiveModel {}
#[axum::async_trait] #[axum::async_trait]
pub trait BatchFillable { pub trait BatchFillable {
async fn load_attachments_batch(&self, db: &DatabaseConnection) -> Result<std::collections::BTreeMap<String, Vec<Model>>, DbErr>; async fn load_attachments_batch(&self, db: &DatabaseConnection) -> Result<std::collections::BTreeMap<String, Vec<Model>>, DbErr>;

View file

@ -4,7 +4,8 @@ use sea_orm::entity::prelude::*;
#[sea_orm(table_name = "configs")] #[sea_orm(table_name = "configs")]
pub struct Model { pub struct Model {
#[sea_orm(primary_key)] #[sea_orm(primary_key)]
pub id: String, pub id: i32,
pub actor: i32,
pub accept_follow_requests: bool, pub accept_follow_requests: bool,
pub show_followers_count: bool, pub show_followers_count: bool,
pub show_following_count: bool, pub show_following_count: bool,
@ -15,7 +16,7 @@ pub struct Model {
impl Default for Model { impl Default for Model {
fn default() -> Self { fn default() -> Self {
Model { Model {
id: "".to_string(), id: 0, actor: 0,
accept_follow_requests: true, accept_follow_requests: true,
show_following_count: true, show_following_count: true,
show_following: true, show_following: true,
@ -28,16 +29,18 @@ impl Default for Model {
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation { pub enum Relation {
#[sea_orm( #[sea_orm(
belongs_to = "super::user::Entity", belongs_to = "super::actor::Entity",
from = "Column::Id", from = "Column::Actor",
to = "super::user::Column::Id" to = "super::actor::Column::Id",
on_update = "Cascade",
on_delete = "Cascade"
)] )]
User, Actors,
} }
impl Related<super::user::Entity> for Entity { impl Related<super::actor::Entity> for Entity {
fn to() -> RelationDef { fn to() -> RelationDef {
Relation::User.def() Relation::Actors.def()
} }
} }

View file

@ -4,24 +4,27 @@ use sea_orm::entity::prelude::*;
#[sea_orm(table_name = "credentials")] #[sea_orm(table_name = "credentials")]
pub struct Model { pub struct Model {
#[sea_orm(primary_key)] #[sea_orm(primary_key)]
pub id: String, pub id: i32,
pub email: String, pub actor: i32,
pub login: String,
pub password: String, pub password: String,
} }
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation { pub enum Relation {
#[sea_orm( #[sea_orm(
belongs_to = "super::user::Entity", belongs_to = "super::actor::Entity",
from = "Column::Id", from = "Column::Actor",
to = "super::user::Column::Id" to = "super::actor::Column::Id",
on_update = "Cascade",
on_delete = "Cascade"
)] )]
User, Actors,
} }
impl Related<super::user::Entity> for Entity { impl Related<super::actor::Entity> for Entity {
fn to() -> RelationDef { fn to() -> RelationDef {
Relation::User.def() Relation::Actors.def()
} }
} }

View file

@ -4,10 +4,10 @@ use sea_orm::entity::prelude::*;
#[sea_orm(table_name = "deliveries")] #[sea_orm(table_name = "deliveries")]
pub struct Model { pub struct Model {
#[sea_orm(primary_key)] #[sea_orm(primary_key)]
pub id: i64, pub id: i32,
pub actor: String, pub actor: i32,
pub target: String, pub target: String,
pub activity: String, pub activity: i32,
pub created: ChronoDateTimeUtc, pub created: ChronoDateTimeUtc,
pub not_before: ChronoDateTimeUtc, pub not_before: ChronoDateTimeUtc,
pub attempt: i32, pub attempt: i32,
@ -18,14 +18,30 @@ pub enum Relation {
#[sea_orm( #[sea_orm(
belongs_to = "super::activity::Entity", belongs_to = "super::activity::Entity",
from = "Column::Activity", from = "Column::Activity",
to = "super::activity::Column::Id" to = "super::activity::Column::Id",
on_update = "Cascade",
on_delete = "Cascade"
)] )]
Activity, Activities,
#[sea_orm(
belongs_to = "super::actor::Entity",
from = "Column::Actor",
to = "super::actor::Column::Id",
on_update = "Cascade",
on_delete = "Cascade"
)]
Actors,
} }
impl Related<super::activity::Entity> for Entity { impl Related<super::activity::Entity> for Entity {
fn to() -> RelationDef { fn to() -> RelationDef {
Relation::Activity.def() Relation::Activities.def()
}
}
impl Related<super::actor::Entity> for Entity {
fn to() -> RelationDef {
Relation::Actors.def()
} }
} }

View file

@ -1,28 +1,30 @@
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
#[sea_orm(table_name = "shares")] #[sea_orm(table_name = "hashtags")]
pub struct Model { pub struct Model {
#[sea_orm(primary_key)] #[sea_orm(primary_key)]
pub id: i64, pub id: i32,
pub actor: String, pub object: i32,
pub shares: String, pub name: String,
pub date: ChronoDateTimeUtc, pub published: ChronoDateTimeUtc,
} }
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation { pub enum Relation {
#[sea_orm( #[sea_orm(
belongs_to = "super::object::Entity", belongs_to = "super::object::Entity",
from = "Column::Shares", from = "Column::Object",
to = "super::object::Column::Id", to = "super::object::Column::Id",
on_update = "Cascade",
on_delete = "Cascade"
)] )]
Object Objects,
} }
impl Related<super::object::Entity> for Entity { impl Related<super::object::Entity> for Entity {
fn to() -> RelationDef { fn to() -> RelationDef {
Relation::Object.def() Relation::Objects.def()
} }
} }

39
src/model/instance.rs Normal file
View file

@ -0,0 +1,39 @@
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
#[sea_orm(table_name = "instances")]
pub struct Model {
#[sea_orm(primary_key)]
pub id: i32,
pub name: Option<String>,
pub domain: String,
pub software: Option<String>,
pub version: Option<String>,
pub down_since: Option<ChronoDateTimeUtc>,
pub users: Option<i32>,
pub posts: Option<i32>,
pub published: ChronoDateTimeUtc,
pub updated: ChronoDateTimeUtc,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(has_many = "super::actor::Entity")]
Actors,
#[sea_orm(has_many = "super::addressing::Entity")]
Addressing,
}
impl Related<super::actor::Entity> for Entity {
fn to() -> RelationDef {
Relation::Actors.def()
}
}
impl Related<super::addressing::Entity> for Entity {
fn to() -> RelationDef {
Relation::Addressing.def()
}
}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -4,25 +4,41 @@ use sea_orm::entity::prelude::*;
#[sea_orm(table_name = "likes")] #[sea_orm(table_name = "likes")]
pub struct Model { pub struct Model {
#[sea_orm(primary_key)] #[sea_orm(primary_key)]
pub id: i64, pub id: i32,
pub actor: String, pub actor: i32,
pub likes: String, pub likes: i32,
pub date: ChronoDateTimeUtc, pub published: ChronoDateTimeUtc,
} }
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation { pub enum Relation {
#[sea_orm(
belongs_to = "super::actor::Entity",
from = "Column::Actor",
to = "super::actor::Column::Id",
on_update = "Cascade",
on_delete = "Cascade"
)]
Actors,
#[sea_orm( #[sea_orm(
belongs_to = "super::object::Entity", belongs_to = "super::object::Entity",
from = "Column::Likes", from = "Column::Likes",
to = "super::object::Column::Id", to = "super::object::Column::Id",
on_update = "Cascade",
on_delete = "Cascade"
)] )]
Object Objects,
}
impl Related<super::actor::Entity> for Entity {
fn to() -> RelationDef {
Relation::Actors.def()
}
} }
impl Related<super::object::Entity> for Entity { impl Related<super::object::Entity> for Entity {
fn to() -> RelationDef { fn to() -> RelationDef {
Relation::Object.def() Relation::Objects.def()
} }
} }

45
src/model/mention.rs Normal file
View file

@ -0,0 +1,45 @@
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
#[sea_orm(table_name = "mentions")]
pub struct Model {
#[sea_orm(primary_key)]
pub id: i32,
pub object: i32,
pub actor: i32,
pub published: ChronoDateTimeUtc,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::actor::Entity",
from = "Column::Actor",
to = "super::actor::Column::Id",
on_update = "Cascade",
on_delete = "Cascade"
)]
Actors,
#[sea_orm(
belongs_to = "super::object::Entity",
from = "Column::Object",
to = "super::object::Column::Id",
on_update = "Cascade",
on_delete = "Cascade"
)]
Objects,
}
impl Related<super::actor::Entity> for Entity {
fn to() -> RelationDef {
Relation::Actors.def()
}
}
impl Related<super::object::Entity> for Entity {
fn to() -> RelationDef {
Relation::Objects.def()
}
}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -1,18 +1,23 @@
pub mod actor;
pub mod object; pub mod object;
pub mod activity; pub mod activity;
pub mod user;
pub mod config;
pub mod relay; pub mod config;
pub mod relation;
pub mod addressing;
pub mod share;
pub mod like;
pub mod credential; pub mod credential;
pub mod session; pub mod session;
pub mod instance;
pub mod delivery; pub mod delivery;
pub mod relation;
pub mod announce;
pub mod like;
pub mod hashtag;
pub mod mention;
pub mod attachment; pub mod attachment;
pub mod application;
pub mod addressing;
#[derive(Debug, Clone, thiserror::Error)] #[derive(Debug, Clone, thiserror::Error)]
#[error("missing required field: '{0}'")] #[error("missing required field: '{0}'")]

View file

@ -9,57 +9,137 @@ use super::Audience;
#[sea_orm(table_name = "objects")] #[sea_orm(table_name = "objects")]
pub struct Model { pub struct Model {
#[sea_orm(primary_key)] #[sea_orm(primary_key)]
pub id: String, pub id: i32,
pub object_type: apb::ObjectType, #[sea_orm(unique)]
pub attributed_to: Option<String>, pub ap_id: String,
pub object_type: String,
pub attributed_to: Option<i32>,
pub name: Option<String>, pub name: Option<String>,
pub summary: Option<String>, pub summary: Option<String>,
pub content: Option<String>, pub content: Option<String>,
pub likes: i64,
pub shares: i64,
pub comments: i64,
pub context: Option<String>,
pub in_reply_to: Option<String>,
pub cc: Audience,
pub bcc: Audience,
pub to: Audience,
pub bto: Audience,
pub url: Option<String>,
pub published: ChronoDateTimeUtc,
pub updated: Option<ChronoDateTimeUtc>,
pub sensitive: bool, pub sensitive: bool,
pub in_reply_to: Option<String>,
pub url: Option<String>,
pub likes: i32,
pub announces: i32,
pub replies: i32,
pub context: Option<String>,
pub to: Option<Json>,
pub bto: Option<Json>,
pub cc: Option<Json>,
pub bcc: Option<Json>,
pub published: ChronoDateTimeUtc,
pub updated: ChronoDateTimeUtc,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(has_many = "super::activity::Entity")]
Activities,
#[sea_orm(
belongs_to = "super::actor::Entity",
from = "Column::AttributedTo",
to = "super::actor::Column::Id",
on_update = "Cascade",
on_delete = "NoAction"
)]
Actors,
#[sea_orm(has_many = "super::addressing::Entity")]
Addressing,
#[sea_orm(has_many = "super::announce::Entity")]
Announces,
#[sea_orm(has_many = "super::attachment::Entity")]
Attachments,
#[sea_orm(has_many = "super::hashtag::Entity")]
Hashtags,
#[sea_orm(has_many = "super::like::Entity")]
Likes,
#[sea_orm(has_many = "super::mention::Entity")]
Mentions,
}
impl Related<super::activity::Entity> for Entity {
fn to() -> RelationDef {
Relation::Activities.def()
}
}
impl Related<super::actor::Entity> for Entity {
fn to() -> RelationDef {
Relation::Actors.def()
}
}
impl Related<super::addressing::Entity> for Entity {
fn to() -> RelationDef {
Relation::Addressing.def()
}
}
impl Related<super::announce::Entity> for Entity {
fn to() -> RelationDef {
Relation::Announces.def()
}
}
impl Related<super::attachment::Entity> for Entity {
fn to() -> RelationDef {
Relation::Attachments.def()
}
}
impl Related<super::hashtag::Entity> for Entity {
fn to() -> RelationDef {
Relation::Hashtags.def()
}
}
impl Related<super::like::Entity> for Entity {
fn to() -> RelationDef {
Relation::Likes.def()
}
}
impl Related<super::mention::Entity> for Entity {
fn to() -> RelationDef {
Relation::Mentions.def()
}
}
impl ActiveModelBehavior for ActiveModel {}
impl ActiveModel {
pub fn new(object: &impl apb::Object) -> Result<Self, super::FieldError> {
Ok(ActiveModel {
id: sea_orm::ActiveValue::NotSet,
ap_id: sea_orm::ActiveValue::Set(object.id().ok_or(super::FieldError("id"))?.to_string()),
object_type: sea_orm::ActiveValue::Set(object.object_type().ok_or(super::FieldError("type"))?),
attributed_to: sea_orm::ActiveValue::Set(object.attributed_to().id()),
name: sea_orm::ActiveValue::Set(object.name().map(|x| x.to_string())),
summary: sea_orm::ActiveValue::Set(object.summary().map(|x| x.to_string())),
content: sea_orm::ActiveValue::Set(object.content().map(|x| x.to_string())),
context: sea_orm::ActiveValue::Set(object.context().id()),
in_reply_to: sea_orm::ActiveValue::Set(object.in_reply_to().id()),
published: sea_orm::ActiveValue::Set(object.published().ok_or(super::FieldError("published"))?),
updated: sea_orm::ActiveValue::Set(object.updated()),
url: sea_orm::ActiveValue::Set(object.url().id()),
replies: sea_orm::ActiveValue::Set(object.replies().get()
.map_or(0, |x| x.total_items().unwrap_or(0)) as i64),
likes: sea_orm::ActiveValue::Set(object.likes().get()
.map_or(0, |x| x.total_items().unwrap_or(0)) as i64),
announces: sea_orm::ActiveValue::Set(object.shares().get()
.map_or(0, |x| x.total_items().unwrap_or(0)) as i64),
to: sea_orm::ActiveValue::Set(object.to().into()),
bto: sea_orm::ActiveValue::Set(object.bto().into()),
cc: sea_orm::ActiveValue::Set(object.cc().into()),
bcc: sea_orm::ActiveValue::Set(object.bcc().into()),
sensitive: sea_orm::ActiveValue::Set(object.sensitive().unwrap_or(false)),
})
}
} }
impl Model { impl Model {
pub fn new(object: &impl apb::Object) -> Result<Self, super::FieldError> {
Ok(Model {
id: object.id().ok_or(super::FieldError("id"))?.to_string(),
object_type: object.object_type().ok_or(super::FieldError("type"))?,
attributed_to: object.attributed_to().id(),
name: object.name().map(|x| x.to_string()),
summary: object.summary().map(|x| x.to_string()),
content: object.content().map(|x| x.to_string()),
context: object.context().id(),
in_reply_to: object.in_reply_to().id(),
published: object.published().ok_or(super::FieldError("published"))?,
updated: object.updated(),
url: object.url().id(),
comments: object.replies().get()
.map_or(0, |x| x.total_items().unwrap_or(0)) as i64,
likes: object.likes().get()
.map_or(0, |x| x.total_items().unwrap_or(0)) as i64,
shares: object.shares().get()
.map_or(0, |x| x.total_items().unwrap_or(0)) as i64,
to: object.to().into(),
bto: object.bto().into(),
cc: object.cc().into(),
bcc: object.bcc().into(),
sensitive: object.sensitive().unwrap_or(false),
})
}
pub fn ap(self) -> serde_json::Value { pub fn ap(self) -> serde_json::Value {
serde_json::Value::new_object() serde_json::Value::new_object()
.set_id(Some(&self.id)) .set_id(Some(&self.id))
@ -72,7 +152,7 @@ impl Model {
.set_conversation(apb::Node::maybe_link(self.context.clone())) // duplicate context for mastodon .set_conversation(apb::Node::maybe_link(self.context.clone())) // duplicate context for mastodon
.set_in_reply_to(apb::Node::maybe_link(self.in_reply_to.clone())) .set_in_reply_to(apb::Node::maybe_link(self.in_reply_to.clone()))
.set_published(Some(self.published)) .set_published(Some(self.published))
.set_updated(self.updated) .set_updated(Some(self.updated))
.set_to(apb::Node::links(self.to.0.clone())) .set_to(apb::Node::links(self.to.0.clone()))
.set_bto(apb::Node::Empty) .set_bto(apb::Node::Empty)
.set_cc(apb::Node::links(self.cc.0.clone())) .set_cc(apb::Node::links(self.cc.0.clone()))
@ -97,69 +177,6 @@ impl Model {
} }
} }
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(has_many = "super::activity::Entity")]
Activity,
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::AttributedTo",
to = "super::user::Column::Id",
)]
User,
#[sea_orm(has_many = "super::addressing::Entity")]
Addressing,
#[sea_orm(has_many = "super::attachment::Entity")]
Attachment,
#[sea_orm(has_many = "super::like::Entity")]
Like,
#[sea_orm(has_many = "super::share::Entity")]
Share,
}
impl Related<super::activity::Entity> for Entity {
fn to() -> RelationDef {
Relation::Activity.def()
}
}
impl Related<super::user::Entity> for Entity {
fn to() -> RelationDef {
Relation::User.def()
}
}
impl Related<super::addressing::Entity> for Entity {
fn to() -> RelationDef {
Relation::Addressing.def()
}
}
impl Related<super::attachment::Entity> for Entity {
fn to() -> RelationDef {
Relation::Attachment.def()
}
}
impl Related<super::like::Entity> for Entity {
fn to() -> RelationDef {
Relation::Like.def()
}
}
impl Related<super::share::Entity> for Entity {
fn to() -> RelationDef {
Relation::Share.def()
}
}
impl ActiveModelBehavior for ActiveModel {}
impl apb::target::Addressed for Model { impl apb::target::Addressed for Model {
fn addressed(&self) -> Vec<String> { fn addressed(&self) -> Vec<String> {
let mut to : Vec<String> = self.to.0.clone(); let mut to : Vec<String> = self.to.0.clone();

View file

@ -4,13 +4,47 @@ use sea_orm::entity::prelude::*;
#[sea_orm(table_name = "relations")] #[sea_orm(table_name = "relations")]
pub struct Model { pub struct Model {
#[sea_orm(primary_key)] #[sea_orm(primary_key)]
pub id: i64, pub id: i32,
pub follower: String, pub follower: i32,
pub following: String, pub following: i32,
pub accept: Option<i32>,
pub activity: i32,
} }
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {} pub enum Relation {
// TODO how to represent this User-to-User relation in sea orm?? #[sea_orm(
belongs_to = "super::activity::Entity",
from = "Column::Accept",
to = "super::activity::Column::Id",
on_update = "Cascade",
on_delete = "NoAction"
)]
Activities2,
#[sea_orm(
belongs_to = "super::activity::Entity",
from = "Column::Activity",
to = "super::activity::Column::Id",
on_update = "Cascade",
on_delete = "NoAction"
)]
Activities1,
#[sea_orm(
belongs_to = "super::actor::Entity",
from = "Column::Follower",
to = "super::actor::Column::Id",
on_update = "Cascade",
on_delete = "Cascade"
)]
Actors2,
#[sea_orm(
belongs_to = "super::actor::Entity",
from = "Column::Following",
to = "super::actor::Column::Id",
on_update = "Cascade",
on_delete = "Cascade"
)]
Actors1,
}
impl ActiveModelBehavior for ActiveModel {} impl ActiveModelBehavior for ActiveModel {}

View file

@ -1,16 +0,0 @@
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
#[sea_orm(table_name = "relays")]
pub struct Model {
#[sea_orm(primary_key)]
pub id: String,
pub accepted: bool,
pub forwarding: bool,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {}
// TODO how to represent this User-to-User relation in sea orm??
impl ActiveModelBehavior for ActiveModel {}

View file

@ -4,24 +4,27 @@ use sea_orm::entity::prelude::*;
#[sea_orm(table_name = "sessions")] #[sea_orm(table_name = "sessions")]
pub struct Model { pub struct Model {
#[sea_orm(primary_key)] #[sea_orm(primary_key)]
pub id: String, pub id: i32,
pub actor: String, pub actor: i32,
pub secret: String,
pub expires: ChronoDateTimeUtc, pub expires: ChronoDateTimeUtc,
} }
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation { pub enum Relation {
#[sea_orm( #[sea_orm(
belongs_to = "super::user::Entity", belongs_to = "super::actor::Entity",
from = "Column::Actor", from = "Column::Actor",
to = "super::user::Column::Id" to = "super::actor::Column::Id",
on_update = "Cascade",
on_delete = "Cascade"
)] )]
User, Actors,
} }
impl Related<super::user::Entity> for Entity { impl Related<super::actor::Entity> for Entity {
fn to() -> RelationDef { fn to() -> RelationDef {
Relation::User.def() Relation::Actors.def()
} }
} }