relay/src/data/node.rs

228 lines
5.9 KiB
Rust
Raw Normal View History

2021-02-10 04:05:06 +00:00
use crate::{
db::{Contact, Db, Info, Instance},
2021-09-18 17:55:39 +00:00
error::Error,
};
2021-02-10 04:05:06 +00:00
use activitystreams::url::Url;
use std::time::{Duration, SystemTime};
2021-09-18 17:55:39 +00:00
#[derive(Clone, Debug)]
pub struct NodeCache {
db: Db,
2021-02-10 04:05:06 +00:00
}
2021-09-21 19:32:25 +00:00
#[derive(Clone, serde::Deserialize, serde::Serialize)]
2021-02-10 04:05:06 +00:00
pub struct Node {
pub(crate) base: Url,
pub(crate) info: Option<Info>,
pub(crate) instance: Option<Instance>,
pub(crate) contact: Option<Contact>,
}
2021-09-21 19:32:25 +00:00
impl std::fmt::Debug for Node {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Node")
.field("base", &self.base.to_string())
.field("info", &self.info)
.field("instance", &self.instance)
.field("contact", &self.contact)
.finish()
}
}
impl NodeCache {
2021-02-10 04:05:06 +00:00
pub(crate) fn new(db: Db) -> Self {
NodeCache { db }
}
2021-09-18 17:55:39 +00:00
#[tracing::instrument(name = "Get nodes")]
pub(crate) async fn nodes(&self) -> Result<Vec<Node>, Error> {
2021-02-10 04:05:06 +00:00
let infos = self.db.connected_info().await?;
let instances = self.db.connected_instance().await?;
let contacts = self.db.connected_contact().await?;
2021-02-10 04:05:06 +00:00
let vec = self
.db
.connected_ids()
.await?
.into_iter()
.map(move |actor_id| {
2021-11-23 22:19:59 +00:00
let info = infos.get(&actor_id).cloned();
let instance = instances.get(&actor_id).cloned();
let contact = contacts.get(&actor_id).cloned();
2021-02-10 04:05:06 +00:00
Node::new(actor_id)
.info(info)
.instance(instance)
.contact(contact)
})
2021-02-10 04:05:06 +00:00
.collect();
2021-02-10 04:05:06 +00:00
Ok(vec)
}
2021-09-21 19:32:25 +00:00
#[tracing::instrument(name = "Is NodeInfo Outdated", fields(actor_id = actor_id.to_string().as_str()))]
2021-02-10 04:05:06 +00:00
pub(crate) async fn is_nodeinfo_outdated(&self, actor_id: Url) -> bool {
self.db
.info(actor_id)
.await
.map(|opt| opt.map(|info| info.outdated()).unwrap_or(true))
.unwrap_or(true)
}
2021-09-21 19:32:25 +00:00
#[tracing::instrument(name = "Is Contact Outdated", fields(actor_id = actor_id.to_string().as_str()))]
2021-02-10 04:05:06 +00:00
pub(crate) async fn is_contact_outdated(&self, actor_id: Url) -> bool {
self.db
.contact(actor_id)
.await
.map(|opt| opt.map(|contact| contact.outdated()).unwrap_or(true))
.unwrap_or(true)
}
2021-09-21 19:32:25 +00:00
#[tracing::instrument(name = "Is Instance Outdated", fields(actor_id = actor_id.to_string().as_str()))]
2021-02-10 04:05:06 +00:00
pub(crate) async fn is_instance_outdated(&self, actor_id: Url) -> bool {
self.db
.instance(actor_id)
.await
.map(|opt| opt.map(|instance| instance.outdated()).unwrap_or(true))
.unwrap_or(true)
}
2021-09-21 19:32:25 +00:00
#[tracing::instrument(name = "Save node info", fields(actor_id = actor_id.to_string().as_str(), software, version, reg))]
2021-02-10 04:05:06 +00:00
pub(crate) async fn set_info(
&self,
2021-02-10 04:05:06 +00:00
actor_id: Url,
software: String,
version: String,
reg: bool,
2021-09-18 17:55:39 +00:00
) -> Result<(), Error> {
2021-02-10 04:05:06 +00:00
self.db
.save_info(
actor_id,
Info {
software,
version,
reg,
updated: SystemTime::now(),
},
)
.await
}
2021-09-21 19:32:25 +00:00
#[tracing::instrument(
name = "Save instance info",
fields(
actor_id = actor_id.to_string().as_str(),
title,
description,
version,
reg,
requires_approval
)
)]
2021-02-10 04:05:06 +00:00
pub(crate) async fn set_instance(
&self,
2021-02-10 04:05:06 +00:00
actor_id: Url,
title: String,
description: String,
version: String,
reg: bool,
requires_approval: bool,
2021-09-18 17:55:39 +00:00
) -> Result<(), Error> {
2021-02-10 04:05:06 +00:00
self.db
.save_instance(
actor_id,
Instance {
title,
description,
version,
reg,
requires_approval,
updated: SystemTime::now(),
},
)
.await
}
2021-09-21 19:32:25 +00:00
#[tracing::instrument(
name = "Save contact info",
fields(
actor_id = actor_id.to_string().as_str(),
username,
display_name,
url = url.to_string().as_str(),
avatar = avatar.to_string().as_str()
)
)]
2021-02-10 04:05:06 +00:00
pub(crate) async fn set_contact(
&self,
2021-02-10 04:05:06 +00:00
actor_id: Url,
username: String,
display_name: String,
2020-06-20 04:11:02 +00:00
url: Url,
avatar: Url,
2021-09-18 17:55:39 +00:00
) -> Result<(), Error> {
self.db
2021-02-10 04:05:06 +00:00
.save_contact(
actor_id,
Contact {
username,
display_name,
url,
avatar,
updated: SystemTime::now(),
},
)
2021-02-10 04:05:06 +00:00
.await
}
}
impl Node {
2021-02-10 04:05:06 +00:00
fn new(mut url: Url) -> Self {
url.set_fragment(None);
url.set_query(None);
url.set_path("");
Node {
2020-06-20 04:11:02 +00:00
base: url,
info: None,
instance: None,
contact: None,
}
}
2021-02-10 04:05:06 +00:00
fn info(mut self, info: Option<Info>) -> Self {
self.info = info;
self
}
2021-02-10 04:05:06 +00:00
fn instance(mut self, instance: Option<Instance>) -> Self {
self.instance = instance;
self
}
2021-02-10 04:05:06 +00:00
fn contact(mut self, contact: Option<Contact>) -> Self {
self.contact = contact;
self
}
}
static TEN_MINUTES: Duration = Duration::from_secs(60 * 10);
impl Info {
2021-02-10 04:05:06 +00:00
pub(crate) fn outdated(&self) -> bool {
self.updated + TEN_MINUTES < SystemTime::now()
}
}
impl Instance {
2021-02-10 04:05:06 +00:00
pub(crate) fn outdated(&self) -> bool {
self.updated + TEN_MINUTES < SystemTime::now()
}
}
impl Contact {
2021-02-10 04:05:06 +00:00
pub(crate) fn outdated(&self) -> bool {
self.updated + TEN_MINUTES < SystemTime::now()
}
}