main: implement nodeinfo 2.1

This commit is contained in:
Astro 2023-05-05 21:47:21 +02:00
parent 12ead51001
commit f6aab8998e
3 changed files with 62 additions and 0 deletions

View file

@ -2,6 +2,8 @@
name = "buzzrelay" name = "buzzrelay"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
repository = "https://github.com/astro/buzzrelay"
homepage = "https://relay.fedi.buzz"
[dependencies] [dependencies]
axum = "0.6" axum = "0.6"

View file

@ -18,6 +18,8 @@ struct DatabaseInner {
add_follow: Statement, add_follow: Statement,
del_follow: Statement, del_follow: Statement,
get_following_inboxes: Statement, get_following_inboxes: Statement,
get_follows_count: Statement,
get_followers_count: Statement,
} }
impl Database { impl Database {
@ -46,6 +48,12 @@ impl Database {
let get_following_inboxes = client.prepare("SELECT DISTINCT inbox FROM follows WHERE actor=$1") let get_following_inboxes = client.prepare("SELECT DISTINCT inbox FROM follows WHERE actor=$1")
.await .await
.unwrap(); .unwrap();
let get_follows_count = client.prepare("SELECT COUNT(id) FROM follows")
.await
.unwrap();
let get_followers_count = client.prepare("SELECT COUNT(DISTINCT id) FROM follows")
.await
.unwrap();
Database { Database {
inner: Arc::new(DatabaseInner { inner: Arc::new(DatabaseInner {
@ -53,6 +61,8 @@ impl Database {
add_follow, add_follow,
del_follow, del_follow,
get_following_inboxes, get_following_inboxes,
get_follows_count,
get_followers_count,
}), }),
} }
} }
@ -85,4 +95,16 @@ impl Database {
.map(|row| row.get(0)) .map(|row| row.get(0))
) )
} }
pub async fn get_follows_count(&self) -> Result<i64, Error> {
let row = self.inner.client.query_one(&self.inner.get_follows_count, &[])
.await?;
Ok(row.get(0))
}
pub async fn get_followers_count(&self) -> Result<i64, Error> {
let row = self.inner.client.query_one(&self.inner.get_followers_count, &[])
.await?;
Ok(row.get(0))
}
} }

View file

@ -231,6 +231,43 @@ async fn post_relay(
} }
} }
async fn nodeinfo(axum::extract::State(state): axum::extract::State<State>) -> Response {
let follows_count = state.database.get_follows_count()
.await
.unwrap_or(0);
let followers_count = state.database.get_followers_count()
.await
.unwrap_or(0);
Json(json!({
"version": "2.1",
"software": {
"name": env!("CARGO_PKG_NAME"),
"version": env!("CARGO_PKG_VERSION"),
"repository": env!("CARGO_PKG_REPOSITORY"),
"homepage": env!("CARGO_PKG_HOMEPAGE"),
},
"protocols": ["activitypub"],
"services": {
"inbound": [],
"outbound": []
},
"openRegistrations": false,
"usage": {
"users": {
"total": followers_count,
"activeHalfyear": followers_count,
"activeMonth": followers_count,
},
"localPosts": follows_count,
"localComments": 0
},
"metadata": {
"rust_version": env!("CARGO_PKG_RUST_VERSION"),
}
})).into_response()
}
#[tokio::main] #[tokio::main]
async fn main() { async fn main() {
exit_on_panic(); exit_on_panic();
@ -280,6 +317,7 @@ async fn main() {
.route("/tag/:tag", get(get_tag_actor).post(post_tag_relay)) .route("/tag/:tag", get(get_tag_actor).post(post_tag_relay))
.route("/instance/:instance", get(get_instance_actor).post(post_instance_relay)) .route("/instance/:instance", get(get_instance_actor).post(post_instance_relay))
.route("/.well-known/webfinger", get(webfinger)) .route("/.well-known/webfinger", get(webfinger))
.route("/.well-known/nodeinfo", get(nodeinfo))
.route("/metrics", get(|| async move { .route("/metrics", get(|| async move {
recorder.render().into_response() recorder.render().into_response()
})) }))