diff --git a/Cargo.toml b/Cargo.toml index 1ba9a864..3f08b715 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,7 +32,7 @@ tokio = { version = "1.35", features = ["full"] } # TODO slim this down sea-orm = { version = "0.12", features = ["macros", "sqlx-sqlite", "runtime-tokio-rustls"] } reqwest = { version = "0.12", features = ["json"] } axum = "0.7" -apb = { path = "apb", features = ["unstructured", "fetch", "orm"] } +apb = { path = "apb", features = ["unstructured", "orm"] } # 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" } # migrations diff --git a/src/main.rs b/src/main.rs index 3c12cff1..25b291c6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,6 +15,8 @@ use sea_orm::{ConnectOptions, Database, EntityTrait, IntoActiveModel}; pub use errors::UpubResult as Result; +use crate::server::fetcher::Fetchable; + pub const VERSION: &str = env!("CARGO_PKG_VERSION"); #[derive(Parser)] @@ -92,7 +94,7 @@ async fn main() { CliCommand::Faker { count } => model::faker::faker(&db, args.domain, count) .await.expect("error creating fake entities"), - CliCommand::Fetch { uri, save } => fetch(&db, &uri, save) + CliCommand::Fetch { uri, save } => fetch(db, args.domain, uri, save) .await.expect("error fetching object"), CliCommand::Serve => { @@ -119,12 +121,15 @@ async fn main() { } -async fn fetch(db: &sea_orm::DatabaseConnection, uri: &str, save: bool) -> reqwest::Result<()> { +async fn fetch(db: sea_orm::DatabaseConnection, domain: String, uri: String, save: bool) -> crate::Result<()> { use apb::{Base, Object}; - let mut node = apb::Node::from(uri); + let ctx = server::Context::new(db, domain) + .await.expect("failed creating server context"); + + let mut node = apb::Node::link(uri.to_string()); tracing::info!("fetching object"); - node.fetch().await?; + node.fetch(&ctx).await?; tracing::info!("fetched node"); let obj = node.get().expect("node still empty after fetch?"); @@ -136,17 +141,17 @@ async fn fetch(db: &sea_orm::DatabaseConnection, uri: &str, save: bool) -> reqwe Some(apb::BaseType::Object(apb::ObjectType::Actor(_))) => { model::user::Entity::insert( model::user::Model::new(obj).unwrap().into_active_model() - ).exec(db).await.unwrap(); + ).exec(ctx.db()).await.unwrap(); }, Some(apb::BaseType::Object(apb::ObjectType::Activity(_))) => { model::activity::Entity::insert( model::activity::Model::new(obj).unwrap().into_active_model() - ).exec(db).await.unwrap(); + ).exec(ctx.db()).await.unwrap(); }, Some(apb::BaseType::Object(apb::ObjectType::Note)) => { model::object::Entity::insert( model::object::Model::new(obj).unwrap().into_active_model() - ).exec(db).await.unwrap(); + ).exec(ctx.db()).await.unwrap(); }, Some(apb::BaseType::Object(t)) => tracing::warn!("not implemented: {:?}", t), Some(apb::BaseType::Link(_)) => tracing::error!("fetched another link?"), diff --git a/src/server/fetcher.rs b/src/server/fetcher.rs index 17a2d0ad..bf960d62 100644 --- a/src/server/fetcher.rs +++ b/src/server/fetcher.rs @@ -122,3 +122,25 @@ impl Fetcher { Ok(object_model) } } + +#[axum::async_trait] +pub trait Fetchable : Sync + Send { + async fn fetch(&mut self, ctx: &crate::server::Context) -> crate::Result<&mut Self>; +} + +#[axum::async_trait] +impl Fetchable for apb::Node { + async fn fetch(&mut self, ctx: &crate::server::Context) -> crate::Result<&mut Self> { + if let apb::Node::Link(uri) = self { + let from = format!("{}{}", ctx.protocol(), ctx.base()); // TODO helper to avoid this? + let pkey = &ctx.app().private_key; + *self = Fetcher::request(Method::GET, uri.href(), None, &from, pkey, ctx.base()) + .await? + .json::() + .await? + .into(); + } + + Ok(self) + } +}