mirror of
https://github.com/spacedriveapp/spacedrive.git
synced 2026-10-23 09:28:38 -04:00
* `sd_init.json` support * bruh * Add `sd_init.json` to developer docs * Ran cargo clippy --fix to fix warnings * Dafuq, cargo clippy --fix messed up cargo fmt --------- Co-authored-by: Ericson Soares <ericson.ds999@gmail.com>
164 lines
3.7 KiB
Rust
164 lines
3.7 KiB
Rust
// ! A system for loading a default set of data on startup. This is ONLY enabled in development builds.
|
|
|
|
use std::{
|
|
path::{Path, PathBuf},
|
|
time::Duration,
|
|
};
|
|
|
|
use crate::{
|
|
library::LibraryConfig,
|
|
location::{delete_location, scan_location, LocationCreateArgs},
|
|
prisma::location,
|
|
};
|
|
use sd_crypto::{
|
|
types::{Algorithm, HashingAlgorithm, OnboardingConfig, Params},
|
|
Protected,
|
|
};
|
|
use serde::Deserialize;
|
|
use tokio::{
|
|
fs::{self, metadata},
|
|
time::sleep,
|
|
};
|
|
use tracing::{info, warn};
|
|
use uuid::Uuid;
|
|
|
|
use crate::library::LibraryManager;
|
|
|
|
#[derive(Deserialize)]
|
|
#[serde(rename_all = "camelCase")]
|
|
pub struct LocationInitConfig {
|
|
path: String,
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
#[serde(rename_all = "camelCase")]
|
|
pub struct LibraryInitConfig {
|
|
id: Uuid,
|
|
name: String,
|
|
description: Option<String>,
|
|
password: String,
|
|
#[serde(default)]
|
|
reset_locations_on_startup: bool,
|
|
locations: Vec<LocationInitConfig>,
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
#[serde(rename_all = "camelCase")]
|
|
pub struct InitConfig {
|
|
#[serde(default)]
|
|
reset_on_startup: bool,
|
|
libraries: Vec<LibraryInitConfig>,
|
|
#[serde(skip, default)]
|
|
path: PathBuf,
|
|
}
|
|
|
|
impl InitConfig {
|
|
pub async fn load(data_dir: &Path) -> Option<Self> {
|
|
let path = std::env::current_dir()
|
|
.unwrap()
|
|
.join(std::env::var("SD_INIT_DATA").unwrap_or("sd_init.json".to_string()));
|
|
|
|
if metadata(&path).await.is_ok() {
|
|
let config = fs::read_to_string(&path).await.unwrap();
|
|
let mut config: InitConfig = serde_json::from_str(&config).unwrap();
|
|
config.path = path;
|
|
|
|
if config.reset_on_startup && data_dir.exists() {
|
|
warn!("previous 'SD_DATA_DIR' was removed on startup!");
|
|
fs::remove_dir_all(&data_dir).await.unwrap();
|
|
}
|
|
|
|
return Some(config);
|
|
}
|
|
|
|
None
|
|
}
|
|
|
|
pub async fn apply(self, library_manager: &LibraryManager) {
|
|
info!("Initializing app from file: {:?}", self.path);
|
|
|
|
for lib in self.libraries {
|
|
let name = lib.name.clone();
|
|
let handle = tokio::spawn(async move {
|
|
loop {
|
|
info!("Initializing library '{name}' from 'sd_init.json'...");
|
|
sleep(Duration::from_secs(1)).await;
|
|
}
|
|
});
|
|
|
|
let library = match library_manager.get_ctx(lib.id).await {
|
|
Some(lib) => lib,
|
|
None => {
|
|
let library = library_manager
|
|
.create_with_uuid(
|
|
lib.id,
|
|
LibraryConfig {
|
|
name: lib.name,
|
|
description: lib.description.unwrap_or("".to_string()),
|
|
},
|
|
OnboardingConfig {
|
|
password: Protected::new(lib.password),
|
|
algorithm: Algorithm::XChaCha20Poly1305,
|
|
hashing_algorithm: HashingAlgorithm::BalloonBlake3(
|
|
Params::Standard,
|
|
),
|
|
},
|
|
)
|
|
.await
|
|
.unwrap();
|
|
|
|
library_manager.get_ctx(library.uuid).await.unwrap()
|
|
}
|
|
};
|
|
|
|
if lib.reset_locations_on_startup {
|
|
let locations = library
|
|
.db
|
|
.location()
|
|
.find_many(vec![])
|
|
.exec()
|
|
.await
|
|
.unwrap();
|
|
|
|
for location in locations {
|
|
warn!("deleting location: {:?}", location.path);
|
|
delete_location(&library, location.id).await.unwrap();
|
|
}
|
|
}
|
|
|
|
for loc in lib.locations {
|
|
if let Some(location) = library
|
|
.db
|
|
.location()
|
|
.find_first(vec![location::path::equals(loc.path.clone())])
|
|
.exec()
|
|
.await
|
|
.unwrap()
|
|
{
|
|
warn!("deleting location: {:?}", location.path);
|
|
delete_location(&library, location.id).await.unwrap();
|
|
}
|
|
|
|
let sd_file = PathBuf::from(&loc.path).join(".spacedrive");
|
|
if sd_file.exists() {
|
|
fs::remove_file(sd_file).await.unwrap();
|
|
}
|
|
|
|
let location = LocationCreateArgs {
|
|
path: loc.path.into(),
|
|
indexer_rules_ids: Vec::new(),
|
|
}
|
|
.create(&library)
|
|
.await
|
|
.unwrap();
|
|
|
|
scan_location(&library, location).await.unwrap();
|
|
}
|
|
|
|
handle.abort();
|
|
}
|
|
|
|
info!("Initialized app from file: {:?}", self.path);
|
|
}
|
|
}
|