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