]> Untitled Git - lemmy.git/blob - server/src/routes/nodeinfo.rs
Merge branch 'admin_settings' into dev
[lemmy.git] / server / src / routes / nodeinfo.rs
1 use crate::db::site_view::SiteView;
2 use crate::version;
3 use crate::Settings;
4 use actix_web::body::Body;
5 use actix_web::web;
6 use actix_web::HttpResponse;
7 use diesel::r2d2::{ConnectionManager, Pool};
8 use diesel::PgConnection;
9 use serde::Serialize;
10
11 pub fn config(cfg: &mut web::ServiceConfig) {
12   cfg
13     .route("/nodeinfo/2.0.json", web::get().to(node_info))
14     .route("/.well-known/nodeinfo", web::get().to(node_info_well_known));
15 }
16
17 async fn node_info_well_known() -> HttpResponse<Body> {
18   let node_info = NodeInfoWellKnown {
19     links: NodeInfoWellKnownLinks {
20       rel: "http://nodeinfo.diaspora.software/ns/schema/2.0".to_string(),
21       href: format!("https://{}/nodeinfo/2.0.json", Settings::get().hostname),
22     },
23   };
24   HttpResponse::Ok().json(node_info)
25 }
26
27 async fn node_info(
28   db: web::Data<Pool<ConnectionManager<PgConnection>>>,
29 ) -> Result<HttpResponse, actix_web::Error> {
30   let res = web::block(move || {
31     let conn = db.get()?;
32     let site_view = match SiteView::read(&conn) {
33       Ok(site_view) => site_view,
34       Err(_) => return Err(format_err!("not_found")),
35     };
36     let protocols = if Settings::get().federation_enabled {
37       vec!["activitypub".to_string()]
38     } else {
39       vec![]
40     };
41     Ok(NodeInfo {
42       version: "2.0".to_string(),
43       software: NodeInfoSoftware {
44         name: "lemmy".to_string(),
45         version: version::VERSION.to_string(),
46       },
47       protocols,
48       usage: NodeInfoUsage {
49         users: NodeInfoUsers {
50           total: site_view.number_of_users,
51         },
52         local_posts: site_view.number_of_posts,
53         local_comments: site_view.number_of_comments,
54         open_registrations: site_view.open_registration,
55       },
56     })
57   })
58   .await
59   .map(|json| HttpResponse::Ok().json(json))
60   .map_err(|_| HttpResponse::InternalServerError())?;
61   Ok(res)
62 }
63
64 #[derive(Serialize)]
65 struct NodeInfoWellKnown {
66   links: NodeInfoWellKnownLinks,
67 }
68
69 #[derive(Serialize)]
70 struct NodeInfoWellKnownLinks {
71   rel: String,
72   href: String,
73 }
74
75 #[derive(Serialize)]
76 struct NodeInfo {
77   version: String,
78   software: NodeInfoSoftware,
79   protocols: Vec<String>,
80   usage: NodeInfoUsage,
81 }
82
83 #[derive(Serialize)]
84 struct NodeInfoSoftware {
85   name: String,
86   version: String,
87 }
88
89 #[derive(Serialize)]
90 #[serde(rename_all = "camelCase")]
91 struct NodeInfoUsage {
92   users: NodeInfoUsers,
93   local_posts: i64,
94   local_comments: i64,
95   open_registrations: bool,
96 }
97
98 #[derive(Serialize)]
99 struct NodeInfoUsers {
100   total: i64,
101 }