Add NodeInfo endpoints (fixes #11)

This commit is contained in:
Bat 2018-06-10 20:33:42 +01:00
parent 7fd152e270
commit d8bd9dbfca
6 changed files with 72 additions and 4 deletions

View File

@ -79,6 +79,7 @@ fn main() {
routes::instance::configure, routes::instance::configure,
routes::instance::post_config, routes::instance::post_config,
routes::instance::shared_inbox, routes::instance::shared_inbox,
routes::instance::nodeinfo,
routes::likes::create, routes::likes::create,
routes::likes::create_auth, routes::likes::create_auth,
@ -120,6 +121,7 @@ fn main() {
routes::user::create, routes::user::create,
routes::well_known::host_meta, routes::well_known::host_meta,
routes::well_known::nodeinfo,
routes::well_known::webfinger routes::well_known::webfinger
]) ])
.manage(init_pool()) .manage(init_pool())

View File

@ -3,7 +3,7 @@ use activitypub::{
object::{Note, properties::ObjectProperties} object::{Note, properties::ObjectProperties}
}; };
use chrono; use chrono;
use diesel::{self, PgConnection, RunQueryDsl, QueryDsl, ExpressionMethods}; use diesel::{self, PgConnection, RunQueryDsl, QueryDsl, ExpressionMethods, dsl::any};
use serde_json; use serde_json;
use activity_pub::{ use activity_pub::{
@ -12,6 +12,7 @@ use activity_pub::{
object::Object object::Object
}; };
use models::{ use models::{
instance::Instance,
posts::Post, posts::Post,
users::User users::User
}; };
@ -110,6 +111,15 @@ impl Comment {
act.object_props.set_id_string(format!("{}/activity", self.ap_url.clone().unwrap())).unwrap(); act.object_props.set_id_string(format!("{}/activity", self.ap_url.clone().unwrap())).unwrap();
act act
} }
pub fn count_local(conn: &PgConnection) -> usize {
use schema::users;
let local_authors = users::table.filter(users::instance_id.eq(Instance::local_id(conn))).select(users::id);
comments::table.filter(comments::author_id.eq(any(local_authors)))
.load::<Comment>(conn)
.expect("Couldn't load local comments")
.len()
}
} }
impl Object for Comment { impl Object for Comment {

View File

@ -1,8 +1,7 @@
use activitypub::activity::Create; use activitypub::activity::Create;
use activitystreams_types::object::{Article, properties::ObjectProperties}; use activitystreams_types::object::{Article, properties::ObjectProperties};
use chrono::NaiveDateTime; use chrono::NaiveDateTime;
use diesel::{self, PgConnection, RunQueryDsl, QueryDsl, ExpressionMethods, BelongingToDsl}; use diesel::{self, PgConnection, RunQueryDsl, QueryDsl, ExpressionMethods, BelongingToDsl, dsl::any};
use diesel::dsl::any;
use serde_json; use serde_json;
use BASE_URL; use BASE_URL;
@ -13,6 +12,7 @@ use activity_pub::{
}; };
use models::{ use models::{
blogs::Blog, blogs::Blog,
instance::Instance,
likes::Like, likes::Like,
post_authors::PostAuthor, post_authors::PostAuthor,
reshares::Reshare, reshares::Reshare,
@ -61,6 +61,17 @@ impl Post {
.into_iter().nth(0) .into_iter().nth(0)
} }
pub fn count_local(conn: &PgConnection) -> usize {
use schema::post_authors;
use schema::users;
let local_authors = users::table.filter(users::instance_id.eq(Instance::local_id(conn))).select(users::id);
let local_posts_id = post_authors::table.filter(post_authors::author_id.eq(any(local_authors))).select(post_authors::post_id);
posts::table.filter(posts::id.eq(any(local_posts_id)))
.load::<Post>(conn)
.expect("Couldn't load local posts")
.len()
}
pub fn find_by_slug(conn: &PgConnection, slug: String) -> Option<Post> { pub fn find_by_slug(conn: &PgConnection, slug: String) -> Option<Post> {
posts::table.filter(posts::slug.eq(slug)) posts::table.filter(posts::slug.eq(slug))
.limit(1) .limit(1)

View File

@ -119,6 +119,13 @@ impl User {
.into_iter().nth(0) .into_iter().nth(0)
} }
pub fn count_local(conn: &PgConnection) -> usize {
users::table.filter(users::instance_id.eq(Instance::local_id(conn)))
.load::<User>(conn)
.expect("Couldn't load local users")
.len()
}
pub fn find_by_email(conn: &PgConnection, email: String) -> Option<User> { pub fn find_by_email(conn: &PgConnection, email: String) -> Option<User> {
users::table.filter(users::email.eq(email)) users::table.filter(users::email.eq(email))
.limit(1) .limit(1)

View File

@ -1,11 +1,12 @@
use rocket::{request::Form, response::Redirect}; use rocket::{request::Form, response::Redirect};
use rocket_contrib::Template; use rocket_contrib::{Json, Template};
use serde_json; use serde_json;
use BASE_URL; use BASE_URL;
use activity_pub::inbox::Inbox; use activity_pub::inbox::Inbox;
use db_conn::DbConn; use db_conn::DbConn;
use models::{ use models::{
comments::Comment,
posts::Post, posts::Post,
users::User, users::User,
instance::* instance::*
@ -75,3 +76,28 @@ fn shared_inbox(conn: DbConn, data: String) -> String {
instance.received(&*conn, act); instance.received(&*conn, act);
String::from("") String::from("")
} }
#[get("/nodeinfo")]
fn nodeinfo(conn: DbConn) -> Json {
Json(json!({
"version": "2.0",
"software": {
"name": "Plume",
"version": "0.1.0"
},
"protocols": ["activitypub"],
"services": {
"inbound": [],
"outbound": []
},
"openRegistrations": true,
"usage": {
"users": {
"total": User::count_local(&*conn)
},
"localPosts": Post::count_local(&*conn),
"localComments": Comment::count_local(&*conn)
},
"metadata": {}
}))
}

View File

@ -6,6 +6,18 @@ use activity_pub::{ap_url, webfinger::Webfinger};
use db_conn::DbConn; use db_conn::DbConn;
use models::{blogs::Blog, users::User}; use models::{blogs::Blog, users::User};
#[get("/.well-known/nodeinfo")]
fn nodeinfo() -> Content<String> {
Content(ContentType::new("application", "jrd+json"), json!({
"links": [
{
"rel": "http://nodeinfo.diaspora.software/ns/schema/2.0",
"href": ap_url(format!("{domain}/nodeinfo", domain = BASE_URL.as_str()))
}
]
}).to_string())
}
#[get("/.well-known/host-meta", format = "application/xml")] #[get("/.well-known/host-meta", format = "application/xml")]
fn host_meta() -> String { fn host_meta() -> String {
format!(r#" format!(r#"