From 0990ccd526dd606e24abdc6ada295fcc70592a45 Mon Sep 17 00:00:00 2001 From: Alex Emmet <111742636+Alex-Emmet@users.noreply.github.com> Date: Thu, 29 Jan 2026 12:11:00 +0100 Subject: [PATCH] [Clean] --- .../anonymous_client_connection.rs | 22 +-- src/calls/call_manager.rs | 68 +------- src/calls/call_util.rs | 100 ++++++++++- src/calls/caller.rs | 2 +- src/data/user.rs | 16 +- src/main.rs | 15 +- src/omega/omega_connection.rs | 23 +-- src/rho/client_connection.rs | 24 ++- src/rho/iota_connection.rs | 5 +- src/rho/rho_connection.rs | 4 +- src/rho/rho_manager.rs | 6 - src/util/config_util.rs | 58 ------- src/util/crypto_util.rs | 23 +-- src/util/file_util.rs | 162 ------------------ src/util/logger.rs | 2 +- src/util/mod.rs | 2 - 16 files changed, 139 insertions(+), 393 deletions(-) delete mode 100644 src/util/config_util.rs delete mode 100644 src/util/file_util.rs diff --git a/src/anonymous_clients/anonymous_client_connection.rs b/src/anonymous_clients/anonymous_client_connection.rs index 3d11cb3..366fb47 100644 --- a/src/anonymous_clients/anonymous_client_connection.rs +++ b/src/anonymous_clients/anonymous_client_connection.rs @@ -12,10 +12,7 @@ use uuid::Uuid; use crate::anonymous_clients::anonymous_manager::generate_username; use crate::calls::call_manager; -use crate::data::{ - communication::{CommunicationType, CommunicationValue, DataTypes}, - user::User, -}; +use crate::data::communication::{CommunicationType, CommunicationValue, DataTypes}; use crate::omega::omega_connection::{WAITING_TASKS, get_omega_connection}; use crate::rho::rho_manager; use crate::util::logger::PrintType; @@ -352,7 +349,7 @@ impl AnonymousClientConnection { return; } }, - None => { + _ => { self.send_error_response(&cv.get_id(), CommunicationType::error_no_call_id) .await; return; @@ -370,7 +367,7 @@ impl AnonymousClientConnection { // Find target RhoConnection let target_rho = match rho_manager::get_rho_con_for_user(receiver_id).await { Some(rho) => rho, - None => { + _ => { self.send_error_response(&cv.get_id(), CommunicationType::error) .await; return; @@ -407,7 +404,7 @@ impl AnonymousClientConnection { return; } }, - None => { + _ => { self.send_error_response(&cv.get_id(), CommunicationType::error) .await; return; @@ -521,15 +518,12 @@ impl AnonymousClientConnection { } /// Check if interested in a user and send notification - pub async fn are_you_interested(self: Arc, user: &User) { + pub async fn are_you_interested(self: Arc, user_id: i64) { let interested_guard = self.clone().get_interested_users().await; - if interested_guard.contains(&user.user_id) { + if interested_guard.contains(&user_id) { let notification = CommunicationValue::new(CommunicationType::client_changed) - .add_data_str(DataTypes::user_id, user.user_id.to_string()) - .add_data_str( - DataTypes::user_state, - format!("{:?}", user.status.to_string()), - ); + .add_data_str(DataTypes::user_id, user_id.to_string()) + .add_data_str(DataTypes::user_state, format!("online")); self.send_message(¬ification).await; } diff --git a/src/calls/call_manager.rs b/src/calls/call_manager.rs index 567bd8b..73e7722 100644 --- a/src/calls/call_manager.rs +++ b/src/calls/call_manager.rs @@ -1,17 +1,11 @@ use dashmap::DashMap; -use livekit::Room; -use livekit_api::services::room::RoomClient; use once_cell::sync::Lazy; -use std::{env, str::FromStr, sync::Arc, time::Duration}; +use std::sync::Arc; use uuid::Uuid; -use crate::{ - calls::{call_group::CallGroup, caller::Caller}, - log, log_err, - util::logger::PrintType, -}; +use crate::calls::{call_group::CallGroup, caller::Caller}; -static CALL_GROUPS: Lazy>> = Lazy::new(|| DashMap::new()); +pub static CALL_GROUPS: Lazy>> = Lazy::new(|| DashMap::new()); pub async fn get_call_invites(user_id: i64) -> Vec> { let mut callers = Vec::new(); @@ -101,59 +95,3 @@ pub async fn add_invite(call_id: Uuid, inviter_id: i64, invitee_id: i64) -> bool } false } - -pub fn garbage_collect_calls() { - tokio::spawn(async move { - loop { - clean_calls().await; - tokio::time::sleep(Duration::from_secs(2)).await; - } - }); -} -pub async fn clean_calls() { - let api_key = match env::var("LIVEKIT_API_KEY") { - Ok(key) => key, - Err(_) => { - log_err!(PrintType::General, "LIVEKIT_API_KEY not set!"); - return; - } - }; - let api_secret = match env::var("LIVEKIT_API_SECRET") { - Ok(secret) => secret, - Err(_) => { - log_err!(PrintType::General, "LIVEKIT_API_SECRET not set!"); - return; - } - }; - let room_service = RoomClient::with_api_key("https:call.tensamin.net", &api_key, &api_secret); - let rooms = room_service.list_rooms(Vec::new()).await.unwrap(); - let mut call_ids: Vec = Vec::new(); - let mut no_users: Vec = Vec::new(); - for room in rooms { - if let Ok(id) = Uuid::from_str(&room.name) { - if room.num_participants == 0 { - no_users.push(id); - } - call_ids.push(id); - } - } - let size_pre = CALL_GROUPS.len(); - for (id, _) in CALL_GROUPS.clone().into_iter() { - if !call_ids.contains(&id) { - CALL_GROUPS.remove(&id); - } - } - for (_, cg) in CALL_GROUPS.clone().into_iter() { - *cg.show.write().await = !no_users.contains(&cg.call_id); - } - - let size_post = CALL_GROUPS.len(); - if size_pre - size_post != 0 { - log!( - PrintType::Call, - "Cleaned {} calls, {} remaining", - size_pre - size_post, - size_post - ); - } -} diff --git a/src/calls/call_util.rs b/src/calls/call_util.rs index 2d06718..105290e 100644 --- a/src/calls/call_util.rs +++ b/src/calls/call_util.rs @@ -1,14 +1,29 @@ -use livekit_api::access_token; +use livekit_api::{ + access_token::{self}, + services::room::RoomClient, +}; use std::env; +use std::str::FromStr; +use std::time::Duration; use uuid::Uuid; -pub fn create_token( - user_id: i64, - call_id: Uuid, - has_admin: bool, -) -> Result { - let api_key = env::var("LIVEKIT_API_KEY").expect("LIVEKIT_API_KEY is not set"); - let api_secret = env::var("LIVEKIT_API_SECRET").expect("LIVEKIT_API_SECRET is not set"); +use crate::{calls::call_manager::CALL_GROUPS, log, log_err, util::logger::PrintType}; + +pub fn create_token(user_id: i64, call_id: Uuid, has_admin: bool) -> Result { + let api_key = match env::var("LIVEKIT_API_KEY") { + Ok(key) => key, + Err(_) => { + log_err!(PrintType::General, "LIVEKIT_API_KEY not set!"); + return Err(()); + } + }; + let api_secret = match env::var("LIVEKIT_API_SECRET") { + Ok(secret) => secret, + Err(_) => { + log_err!(PrintType::General, "LIVEKIT_API_SECRET not set!"); + return Err(()); + } + }; let token = access_token::AccessToken::with_api_key(&api_key, &api_secret) .with_identity(&user_id.to_string()) @@ -21,5 +36,72 @@ pub fn create_token( }) .with_metadata(&format!("{{\"isAdmin\":{}}}", has_admin)) .to_jwt(); - return token; + if let Ok(token) = token { + Ok(token) + } else { + Err(()) + } +} + +pub fn garbage_collect_calls() { + tokio::spawn(async move { + let api_key = match env::var("LIVEKIT_API_KEY") { + Ok(key) => key, + Err(_) => { + log_err!(PrintType::General, "LIVEKIT_API_KEY not set!"); + return; + } + }; + let api_secret = match env::var("LIVEKIT_API_SECRET") { + Ok(secret) => secret, + Err(_) => { + log_err!(PrintType::General, "LIVEKIT_API_SECRET not set!"); + return; + } + }; + let hostname = match env::var("LIVEKI_HOSTNAME") { + Ok(secret) => secret, + Err(_) => { + log_err!(PrintType::General, "LIVEKI_HOSTNAME not set!"); + return; + } + }; + loop { + let room_service = RoomClient::with_api_key(&hostname, &api_key, &api_secret); + clean_calls(room_service).await; + tokio::time::sleep(Duration::from_secs(2)).await; + } + }); +} +pub async fn clean_calls(room_service: RoomClient) { + let rooms = room_service.list_rooms(Vec::new()).await.unwrap(); + let mut call_ids: Vec = Vec::new(); + let mut no_users: Vec = Vec::new(); + for room in rooms { + if let Ok(id) = Uuid::from_str(&room.name) { + if room.num_participants == 0 { + no_users.push(id); + } + call_ids.push(id); + } + } + let size_pre = CALL_GROUPS.len(); + for (id, _) in CALL_GROUPS.clone().into_iter() { + if !call_ids.contains(&id) { + CALL_GROUPS.remove(&id); + } + } + for (_, cg) in CALL_GROUPS.clone().into_iter() { + *cg.show.write().await = !no_users.contains(&cg.call_id); + } + + let size_post = CALL_GROUPS.len(); + if size_pre - size_post != 0 { + log!( + PrintType::Call, + "Cleaned {} calls, {} remaining", + size_pre - size_post, + size_post + ); + } } diff --git a/src/calls/caller.rs b/src/calls/caller.rs index 7a6a600..ceff545 100644 --- a/src/calls/caller.rs +++ b/src/calls/caller.rs @@ -27,7 +27,7 @@ impl Caller { pub fn has_admin(&self) -> bool { self.has_admin } - pub async fn is_timeout(&self) -> bool { + pub async fn is_timeouted(&self) -> bool { *self.timeout.read().await > SystemTime::now() .duration_since(UNIX_EPOCH) diff --git a/src/data/user.rs b/src/data/user.rs index 306699e..0679bef 100644 --- a/src/data/user.rs +++ b/src/data/user.rs @@ -1,19 +1,5 @@ -#[derive(Clone)] -pub struct User { - pub iota_id: i64, - pub user_id: i64, - pub status: UserStatus, -} -impl User { - pub fn new(iota_id: i64, user_id: i64, status: UserStatus) -> Self { - User { - iota_id, - user_id, - status, - } - } -} #[derive(Clone, Copy)] +#[allow(non_camel_case_types)] pub enum UserStatus { online, do_not_disturb, diff --git a/src/main.rs b/src/main.rs index 9bf6478..ac99074 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,11 +18,10 @@ use crate::{ anonymous_clients::{ anonymous_client_connection::AnonymousClientConnection, anonymous_manager, }, - calls::call_manager::garbage_collect_calls, + calls::call_util::garbage_collect_calls, omega::omega_connection::OmegaConnection, rho::{client_connection::ClientConnection, iota_connection::IotaConnection}, util::{ - config_util::CONFIG, crypto_helper::{load_public_key, load_secret_key}, logger::{PrintType, startup}, }, @@ -44,7 +43,11 @@ async fn main() { Arc::new(OmegaConnection::new()).connect(); }); startup(); - let address = format!("{}:{}", &CONFIG.read().await.ip, &CONFIG.read().await.port); + let address = format!( + "{}:{}", + env::var("IP").unwrap_or("0.0.0.0".to_string()), + env::var("PORT").unwrap_or("959".to_string()) + ); let listener = TcpListener::bind(&address).await.unwrap(); log!( @@ -97,7 +100,7 @@ async fn main() { client_conn.handle_close().await; return; } - None => { + _ => { log_in!(PrintType::Client, "Client stream ended"); client_conn.handle_close().await; return; @@ -139,7 +142,7 @@ async fn main() { client_conn.handle_close().await; return; } - None => { + _ => { log_in!(PrintType::Client, "Anonymous Client stream ended"); anonymous_manager::remove_anonymous_user( client_conn.get_user_id().await, @@ -176,7 +179,7 @@ async fn main() { iota_conn.handle_close().await; return; } - None => { + _ => { // Stream ended log_in!(PrintType::Iota, "Iota stream ended"); iota_conn.handle_close().await; diff --git a/src/omega/omega_connection.rs b/src/omega/omega_connection.rs index 162767b..b169c4e 100755 --- a/src/omega/omega_connection.rs +++ b/src/omega/omega_connection.rs @@ -17,17 +17,19 @@ use tokio::{ use tokio_native_tls::TlsStream; use uuid::Uuid; +use crate::log_err; use crate::{ data::{ communication::{CommunicationType, CommunicationValue, DataTypes}, user::UserStatus, }, get_private_key, log, log_in, log_out, - rho::rho_manager::{self, RHO_CONNECTIONS}, - util::crypto_helper::{decrypt_b64, secret_key_to_base64}, - util::logger::PrintType, + rho::rho_manager::{self, RHO_CONNECTIONS, connection_count}, + util::{ + crypto_helper::{decrypt_b64, secret_key_to_base64}, + logger::PrintType, + }, }; -use crate::{log_err, util::crypto_helper::load_public_key}; pub static WAITING_TASKS: Lazy< DashMap, CommunicationValue) -> bool + Send + Sync>>, @@ -159,8 +161,6 @@ impl OmegaConnection { .to_string() })?; - let server_pub_key_obj = load_public_key(server_pub_key).unwrap(); - let decrypted_challenge = decrypt_b64( &secret_key_to_base64(&get_private_key()), server_pub_key, @@ -222,7 +222,8 @@ impl OmegaConnection { let sync_msg = CommunicationValue::new(CommunicationType::sync_client_iota_status) .add_data(DataTypes::iota_ids, JsonValue::Array(connected_iota_ids)) - .add_data(DataTypes::user_ids, JsonValue::Array(connected_user_ids)); + .add_data(DataTypes::user_ids, JsonValue::Array(connected_user_ids)) + .add_data(DataTypes::rho_connections, JsonValue::from(connection_count().await)); selfc.send_message(&sync_msg).await; }); @@ -340,12 +341,6 @@ impl OmegaConnection { } } - pub async fn connect_iota(iota_id: i64, _user_ids: Vec) { - let cv = CommunicationValue::new(CommunicationType::iota_connected) - .add_data(DataTypes::iota_id, JsonValue::from(iota_id)); - OmegaConnection::send_global(cv).await; - } - pub async fn close_iota(iota_id: i64) { let cv = CommunicationValue::new(CommunicationType::iota_disconnected) .add_data(DataTypes::iota_id, JsonValue::from(iota_id)); @@ -459,7 +454,7 @@ impl OmegaConnection { match tokio::time::timeout(timeout, rx.recv()).await { Ok(Some(response_cv)) => Ok(response_cv), - Ok(None) => Err("Failed to receive response, channel was closed.".to_string()), + Ok(_) => Err("Failed to receive response, channel was closed.".to_string()), Err(_) => { WAITING_TASKS.remove(&msg_id); Err(format!( diff --git a/src/rho/client_connection.rs b/src/rho/client_connection.rs index 4928979..7ebdf77 100644 --- a/src/rho/client_connection.rs +++ b/src/rho/client_connection.rs @@ -20,10 +20,9 @@ use crate::util::crypto_helper::{load_public_key, public_key_to_base64}; use crate::util::crypto_util::{DataFormat, SecurePayload}; use crate::util::logger::PrintType; use crate::{ - // calls::call_manager::CallManager, data::{ communication::{CommunicationType, CommunicationValue, DataTypes}, - user::{User, UserStatus}, + user::UserStatus, }, omega::omega_connection::OmegaConnection, }; @@ -163,7 +162,7 @@ impl ClientConnection { let pub_key = match load_public_key(base64_pub) { Some(pk) => pk, - None => { + _ => { self.clone() .send_error_response( &cv.get_id(), @@ -227,7 +226,7 @@ impl ClientConnection { let rho_connection = match rho_manager::get_rho_con_for_user(user_id).await { Some(rho) => rho, - None => { + _ => { self.send_error_response( &cv.get_id(), CommunicationType::error_no_iota, @@ -432,7 +431,7 @@ impl ClientConnection { return; } }, - None => { + _ => { self.send_error_response(&cv.get_id(), CommunicationType::error_no_call_id) .await; return; @@ -450,7 +449,7 @@ impl ClientConnection { // Find target RhoConnection let target_rho = match rho_manager::get_rho_con_for_user(receiver_id).await { Some(rho) => rho, - None => { + _ => { self.send_error_response(&cv.get_id(), CommunicationType::error) .await; return; @@ -487,7 +486,7 @@ impl ClientConnection { return; } }, - None => { + _ => { self.send_error_response(&cv.get_id(), CommunicationType::error) .await; return; @@ -697,15 +696,12 @@ impl ClientConnection { } /// Check if interested in a user and send notification - pub async fn are_you_interested(self: Arc, user: &User) { + pub async fn are_you_interested(self: Arc, user_id: i64) { let interested_guard = self.clone().get_interested_users().await; - if interested_guard.contains(&user.user_id) { + if interested_guard.contains(&user_id) { let notification = CommunicationValue::new(CommunicationType::client_changed) - .add_data_str(DataTypes::user_id, user.user_id.to_string()) - .add_data_str( - DataTypes::user_state, - format!("{:?}", user.status.to_string()), - ); + .add_data_str(DataTypes::user_id, user_id.to_string()) + .add_data_str(DataTypes::user_state, format!("online")); self.send_message(¬ification).await; } diff --git a/src/rho/iota_connection.rs b/src/rho/iota_connection.rs index 4583d3d..5f96b5c 100755 --- a/src/rho/iota_connection.rs +++ b/src/rho/iota_connection.rs @@ -189,7 +189,7 @@ impl IotaConnection { let pub_key = match load_public_key(base64_pub) { Some(pk) => pk, - None => { + _ => { self.send_error_response( &cv.get_id(), CommunicationType::error_invalid_public_key, @@ -594,6 +594,7 @@ impl IotaConnection { } } } + pub async fn await_response( &self, cv: &CommunicationValue, @@ -626,7 +627,7 @@ impl IotaConnection { match tokio::time::timeout(timeout, rx.recv()).await { Ok(Some(response_cv)) => Ok(response_cv), - Ok(None) => Err("Failed to receive response, channel was closed.".to_string()), + Ok(_) => Err("Failed to receive response, channel was closed.".to_string()), Err(_) => { self.waiting_tasks.remove(&msg_id); Err(format!( diff --git a/src/rho/rho_connection.rs b/src/rho/rho_connection.rs index dfc71cc..999fef4 100644 --- a/src/rho/rho_connection.rs +++ b/src/rho/rho_connection.rs @@ -147,10 +147,10 @@ impl RhoConnection { } /// Check if clients are interested in a user - pub async fn are_they_interested(&self, user: &crate::data::user::User) { + pub async fn are_they_interested(&self, user_id: i64) { let connections = self.client_connections.read().await; for connection in connections.iter() { - connection.clone().are_you_interested(user).await; + connection.clone().are_you_interested(user_id).await; } } diff --git a/src/rho/rho_manager.rs b/src/rho/rho_manager.rs index f2b41d3..2334ca6 100644 --- a/src/rho/rho_manager.rs +++ b/src/rho/rho_manager.rs @@ -50,12 +50,6 @@ pub async fn get_rho_by_iota(iota_id: i64) -> Option> { connections.get(&iota_id).map(Arc::clone) } -/// Get all active RhoConnections -pub async fn get_all_connections() -> Vec> { - let connections = RHO_CONNECTIONS.read().await; - connections.values().map(Arc::clone).collect() -} - /// Get the count of active connections pub async fn connection_count() -> usize { let connections = RHO_CONNECTIONS.read().await; diff --git a/src/util/config_util.rs b/src/util/config_util.rs deleted file mode 100644 index d0b9e25..0000000 --- a/src/util/config_util.rs +++ /dev/null @@ -1,58 +0,0 @@ -use crate::util::file_util::load_file; -use once_cell::sync::Lazy; -use serde::{Deserialize, Serialize}; -use tokio::sync::RwLock; -use uuid::Uuid; -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct Config { - pub omega_server: String, - pub auth_server: String, - pub omikron_id: Uuid, - pub keep_people_stored_for: i32, - pub max_data: u64, - pub ip: String, - pub port: u16, -} - -impl Default for Config { - fn default() -> Self { - Self { - omega_server: "omega.tensamin.net".into(), - auth_server: "auth.tensamin.net".into(), - omikron_id: Uuid::parse_str("00000000-0000-0000-0000-000000000000").unwrap_or_default(), - keep_people_stored_for: 90, - max_data: 1000 * 1000 * 1000 * 8, - ip: "0.0.0.0".into(), - port: 959, - } - } -} - -pub static CONFIG: Lazy> = Lazy::new(|| RwLock::new(Config::load())); - -impl Config { - pub fn load() -> Self { - let content = load_file("", "config.json"); - if content.trim().is_empty() { - return Config::default(); - } - - let json = json::parse(&content).unwrap(); - Self { - omega_server: json["omega_server"] - .as_str() - .unwrap_or("omega.tensamin.net") - .into(), - auth_server: json["auth_server"] - .as_str() - .unwrap_or("auth.tensamin.net") - .into(), - omikron_id: Uuid::parse_str(json["omikron_id"].as_str().unwrap_or_default()) - .unwrap_or_default(), - keep_people_stored_for: json["keep_people_stored_for"].as_i64().unwrap_or(90) as i32, - max_data: json["max_data"].as_u64().unwrap_or(8000000000), - ip: json["ip"].as_str().unwrap_or("0.0.0.0").into(), - port: json["port"].as_u64().unwrap_or(959) as u16, - } - } -} diff --git a/src/util/crypto_util.rs b/src/util/crypto_util.rs index 97acab4..0285552 100644 --- a/src/util/crypto_util.rs +++ b/src/util/crypto_util.rs @@ -25,11 +25,8 @@ pub enum DataFormat { Hex, } -// --- Main Class Structure --- pub struct SecurePayload { - /// The internal canonical representation is always raw bytes. inner_data: Vec, - /// The private key of the user associated with this payload instance. private_key: Secret, } @@ -109,22 +106,14 @@ impl SecurePayload { let peer_pub = public_key.into(); let shared_secret = self.private_key.as_diffie_hellman(&peer_pub).unwrap(); - println!( - "Encryption Shared Secret (Hex): {}", - hex::encode(shared_secret.as_bytes()) - ); - - // 3. Key & Nonce Derivation (HKDF) - // We derive 32 bytes for the key and 12 bytes for a deterministic nonce. let hkdf = Hkdf::::new(None, shared_secret.as_bytes()); - let mut okm = [0u8; 44]; // 32 (Key) + 12 (Nonce) + let mut okm = [0u8; 44]; hkdf.expand(b"x448-aes-gcm-no-overhead", &mut okm) .map_err(|_| SecurePayloadError::EncryptionError)?; let key = &okm[..32]; let nonce_bytes = &okm[32..]; - // 4. Encrypt with AES-256-GCM let cipher = Aes256Gcm::new(key.into()); let nonce = Nonce::from_slice(nonce_bytes); @@ -138,7 +127,6 @@ impl SecurePayload { ) .map_err(|_| SecurePayloadError::EncryptionError)?; - // 5. Result is ONLY the ciphertext. No key or nonce is packed. Ok(SecurePayload { inner_data: ciphertext, private_key: Secret::from_bytes(self.private_key.as_bytes()).unwrap(), @@ -160,17 +148,9 @@ impl SecurePayload { &self, peer_public_key_bytes: &[u8; 56], ) -> Result { - // 1. Perform Exchange let peer_pub = PublicKey::from_bytes(peer_public_key_bytes).unwrap(); let shared_secret = self.private_key.as_diffie_hellman(&peer_pub).unwrap(); - // LOGGING: Shared Secret - println!( - "Decryption Shared Secret (Hex): {}", - hex::encode(shared_secret.as_bytes()) - ); - - // 2. Key & Nonce Derivation (Must match encryption exactly) let hkdf = Hkdf::::new(None, shared_secret.as_bytes()); let mut okm = [0u8; 44]; hkdf.expand(b"x448-aes-gcm-no-overhead", &mut okm) @@ -179,7 +159,6 @@ impl SecurePayload { let key = &okm[..32]; let nonce_bytes = &okm[32..]; - // 3. Decrypt with AES-256-GCM let cipher = Aes256Gcm::new(key.into()); let nonce = Nonce::from_slice(nonce_bytes); diff --git a/src/util/file_util.rs b/src/util/file_util.rs deleted file mode 100644 index 774a5e3..0000000 --- a/src/util/file_util.rs +++ /dev/null @@ -1,162 +0,0 @@ -use std::ffi::OsStr; -use std::fs::{self, File}; -use std::io::Read; -use std::path::{Path, PathBuf}; -use sysinfo::System; -use uuid::Uuid; -use walkdir::WalkDir; - -pub fn delete_file(path: &str, name: &str) -> bool { - let dir = Path::new(&get_directory()).join(path); - let file = dir.join(name); - if !file.exists() { - return false; - } - fs::remove_file(file).is_ok() -} - -pub fn delete_directory(path: &str) -> bool { - let dir = Path::new(&get_directory()).join(path); - delete_dir_recursive(&dir) -} - -fn delete_dir_recursive(directory: &Path) -> bool { - if !directory.exists() { - return false; - } - if let Err(e) = fs::remove_dir_all(directory) { - println!( - "[IMPORTANT] Couldn't delete directory {}: {}", - directory.display(), - e - ); - return false; - } - true -} - -pub fn delete_user_directory(user_id: Uuid) { - let user_dir = Path::new(&get_directory()) - .join("users") - .join(user_id.to_string()); - let _ = delete_dir_recursive(&user_dir); -} - -pub fn load_file(path: &str, name: &str) -> String { - let dir = Path::new(&get_directory()).join(path); - let file_path = dir.join(name); - - if !dir.exists() { - if let Err(e) = fs::create_dir_all(&dir) { - println!("[IMPORTANT] Couldn't create directories: {}", e); - return String::new(); - } - return String::new(); - } - - if !file_path.exists() { - if let Err(e) = File::create(&file_path) { - println!("[IMPORTANT] Couldn't create file: {}", e); - } - return String::new(); - } - - let mut content = String::new(); - if let Ok(mut f) = File::open(&file_path) { - let _ = f.read_to_string(&mut content); - } - content -} - -pub fn save_file(path: &str, name: &str, value: &str) { - let dir = Path::new(&get_directory()).join(path); - let file_path = dir.join(name); - - if !dir.exists() { - if let Err(e) = fs::create_dir_all(&dir) { - println!("[IMPORTANT] Couldn't create directories: {}", e); - return; - } - } - - if let Err(e) = fs::write(&file_path, value) { - println!( - "[IMPORTANT] Couldn't write file {}: {}", - file_path.display(), - e - ); - } -} - -pub fn get_children(path: &str) -> Vec { - let dir = Path::new(&get_directory()).join(path); - let mut children = Vec::new(); - if let Ok(entries) = fs::read_dir(&dir) { - for entry in entries { - if let Ok(entry) = entry { - children.push(entry.file_name().to_string_lossy().to_string()); - } - } - } - children -} - -pub fn get_directory() -> String { - let exe = std::env::current_exe().unwrap_or_else(|_| PathBuf::from(".")); - exe.parent() - .unwrap_or(Path::new(".")) - .to_string_lossy() - .to_string() -} - -pub fn used_space() -> u64 { - get_directory_size(&PathBuf::from(get_directory())) -} - -pub fn get_directory_size(directory: &Path) -> u64 { - let mut size = 0; - for entry in WalkDir::new(directory).into_iter().filter_map(|e| e.ok()) { - let path = entry.path(); - if path.is_file() { - if let Ok(metadata) = path.metadata() { - size += path.file_name().unwrap_or(OsStr::new("")).len() as u64; - size += metadata.len(); - } - } - } - size -} - -pub fn get_designed_storage(user_id: Uuid) -> String { - let user_dir = Path::new(&get_directory()) - .join("users") - .join(user_id.to_string()); - design_byte(get_directory_size(&user_dir)) -} - -pub fn design_byte(bytes: u64) -> String { - let mut hr_size = format!("{:.2}B", bytes as f64); - let k = bytes as f64 / 1024.0; - let m = k / 1024.0; - let g = m / 1024.0; - let t = g / 1024.0; - - if t >= 1.0 { - hr_size = format!("{:.2}TB", t); - } else if g >= 1.0 { - hr_size = format!("{:.2}GB", g); - } else if m >= 1.0 { - hr_size = format!("{:.2}MB", m); - } else if k >= 1.0 { - hr_size = format!("{:.2}KB", k); - } - hr_size -} - -pub fn get_used_ram() -> String { - let mut sys = System::new_all(); - sys.refresh_all(); - let used = sys.used_memory() * 1024; // kB to bytes - let total = sys.total_memory() * 1024; - format!("{}/{}", design_byte(used), design_byte(total)) -} diff --git a/src/util/logger.rs b/src/util/logger.rs index d537733..360e520 100644 --- a/src/util/logger.rs +++ b/src/util/logger.rs @@ -56,7 +56,7 @@ pub fn startup() { let ts = fixed_box(&msg.timestamp_ms.to_string(), 13); let sender = match msg.sender { Some(id) => fixed_box(&id.to_string(), 19), - None => fixed_box("", 19), + _ => fixed_box("", 19), }; let line = format!("{} {} {} {}", ts, sender, msg.prefix, msg.message); diff --git a/src/util/mod.rs b/src/util/mod.rs index 6df4f2f..3472249 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -1,5 +1,3 @@ -pub mod config_util; pub mod crypto_helper; pub mod crypto_util; -pub mod file_util; pub mod logger;