use nodeinfo::NodeInfoOwned; use sea_orm::{entity::prelude::*, QuerySelect, SelectColumns}; use crate::errors::UpubError; #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] #[sea_orm(table_name = "instances")] pub struct Model { #[sea_orm(primary_key)] pub internal: i64, #[sea_orm(unique)] pub domain: String, pub name: Option<String>, pub software: Option<String>, pub version: Option<String>, pub icon: Option<String>, pub down_since: Option<ChronoDateTimeUtc>, pub users: Option<i64>, pub posts: Option<i64>, 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 {} impl Entity { pub fn find_by_domain(domain: &str) -> Select<Entity> { Entity::find().filter(Column::Domain.eq(domain)) } pub async fn domain_to_internal(domain: &str, db: &DatabaseConnection) -> crate::Result<i64> { Entity::find() .filter(Column::Domain.eq(domain)) .select_only() .select_column(Column::Internal) .into_tuple::<i64>() .one(db) .await? .ok_or_else(UpubError::not_found) } pub async fn nodeinfo(domain: &str) -> crate::Result<NodeInfoOwned> { Ok( reqwest::get(format!("https://{domain}/nodeinfo/2.0.json")) .await? .json() .await? ) } }