use super::*; pub fn config(cfg: &mut web::ServiceConfig) { cfg .route("/nodeinfo/2.0.json", web::get().to(node_info)) .route("/.well-known/nodeinfo", web::get().to(node_info_well_known)); } async fn node_info_well_known() -> HttpResponse { let node_info = NodeInfoWellKnown { links: NodeInfoWellKnownLinks { rel: "http://nodeinfo.diaspora.software/ns/schema/2.0".to_string(), href: format!("https://{}/nodeinfo/2.0.json", Settings::get().hostname), }, }; HttpResponse::Ok().json(node_info) } async fn node_info( db: web::Data>>, ) -> Result { let res = web::block(move || { let conn = db.get()?; let site_view = match SiteView::read(&conn) { Ok(site_view) => site_view, Err(_) => return Err(format_err!("not_found")), }; let protocols = if Settings::get().federation_enabled { vec!["activitypub".to_string()] } else { vec![] }; Ok(NodeInfo { version: "2.0".to_string(), software: NodeInfoSoftware { name: "lemmy".to_string(), version: version::VERSION.to_string(), }, protocols, usage: NodeInfoUsage { users: NodeInfoUsers { total: site_view.number_of_users, }, local_posts: site_view.number_of_posts, local_comments: site_view.number_of_comments, open_registrations: site_view.open_registration, }, }) }) .await .map(|json| HttpResponse::Ok().json(json)) .map_err(|_| HttpResponse::InternalServerError())?; Ok(res) } #[derive(Serialize)] struct NodeInfoWellKnown { links: NodeInfoWellKnownLinks, } #[derive(Serialize)] struct NodeInfoWellKnownLinks { rel: String, href: String, } #[derive(Serialize)] struct NodeInfo { version: String, software: NodeInfoSoftware, protocols: Vec, usage: NodeInfoUsage, } #[derive(Serialize)] struct NodeInfoSoftware { name: String, version: String, } #[derive(Serialize)] #[serde(rename_all = "camelCase")] struct NodeInfoUsage { users: NodeInfoUsers, local_posts: i64, local_comments: i64, open_registrations: bool, } #[derive(Serialize)] struct NodeInfoUsers { total: i64, }