Files
spacedrive/core/src/api/nodes.rs
T
2023-11-04 09:16:15 +00:00

104 lines
2.7 KiB
Rust

use crate::{invalidate_query, prisma::location, util::MaybeUndefined};
use rspc::{alpha::AlphaRouter, ErrorCode};
use sd_prisma::prisma::instance;
use serde::Deserialize;
use specta::Type;
use tracing::error;
use uuid::Uuid;
use super::{locations::ExplorerItem, utils::library, Ctx, R};
pub(crate) fn mount() -> AlphaRouter<Ctx> {
R.router()
.procedure("edit", {
#[derive(Deserialize, Type)]
pub struct ChangeNodeNameArgs {
pub name: Option<String>,
pub p2p_enabled: Option<bool>,
pub p2p_port: MaybeUndefined<u16>,
}
R.mutation(|node, args: ChangeNodeNameArgs| async move {
if let Some(name) = &args.name {
if name.is_empty() || name.len() > 250 {
return Err(rspc::Error::new(
ErrorCode::BadRequest,
"invalid node name".into(),
));
}
}
let does_p2p_need_refresh =
args.p2p_enabled.is_some() || args.p2p_port.is_defined();
node.config
.write(|mut config| {
if let Some(name) = args.name {
config.name = name;
}
config.p2p.enabled = args.p2p_enabled.unwrap_or(config.p2p.enabled);
if let Some(v) = args.p2p_port.into() {
config.p2p.port = v;
}
})
.await
.map_err(|err| {
error!("Failed to write config: {}", err);
rspc::Error::new(
ErrorCode::InternalServerError,
"error updating config".into(),
)
})?;
// If a P2P config was modified reload it
if does_p2p_need_refresh {
node.p2p
.manager
.update_config(node.config.get().await.p2p.clone())
.await;
}
invalidate_query!(node; node, "nodeState");
Ok(())
})
})
// TODO: add pagination!! and maybe ordering etc
.procedure("listLocations", {
R.with2(library())
// TODO: I don't like this. `node_id` should probs be a machine hash or something cause `node_id` is dynamic in the context of P2P and what does it mean for removable media to be owned by a node?
.query(|(_, library), node_id: Option<Uuid>| async move {
// Be aware multiple instances can exist on a single node. This is generally an edge case but it's possible.
let instances = library
.db
.instance()
.find_many(vec![node_id
.map(|id| instance::node_id::equals(id.as_bytes().to_vec()))
.unwrap_or(instance::id::equals(library.config().instance_id))])
.exec()
.await?;
Ok(library
.db
.location()
.find_many(
instances
.into_iter()
.map(|i| location::instance_id::equals(Some(i.id)))
.collect(),
)
.exec()
.await?
.into_iter()
.map(|location| ExplorerItem::Location {
has_local_thumbnail: false,
thumbnail_key: None,
item: location,
})
.collect::<Vec<_>>())
})
})
}