summaryrefslogtreecommitdiffstats
path: root/server/src/routes/nodeinfo.rs
blob: 829d56b1f9c54fb863b9a8f6069ae84efbef37cb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
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<Body> {
  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<Pool<ConnectionManager<PgConnection>>>,
) -> Result<HttpResponse, actix_web::Error> {
  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<String>,
  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,
}