Omikron Connects Data Sends Identified Users loaded

This commit is contained in:
Alex Emmet 2025-09-07 15:56:48 +02:00
commit a1d8bcbeff
10 changed files with 228 additions and 209 deletions

View file

@ -56,7 +56,7 @@ impl AuthConnector {
if !cv.is_type(CommunicationType::Success) { if !cv.is_type(CommunicationType::Success) {
return None; return None;
} }
Uuid::parse_str(cv.get_data(DataTypes::UserId).unwrap()).ok() Uuid::parse_str(&*cv.get_data(DataTypes::UserId).unwrap().to_string()).ok()
} }
pub async fn get_user(user_id: Uuid) -> Option<AuthUser> { pub async fn get_user(user_id: Uuid) -> Option<AuthUser> {
@ -90,7 +90,7 @@ impl AuthConnector {
let json = res.text().await.ok()?; let json = res.text().await.ok()?;
let mut cv = CommunicationValue::from_json(&json); let mut cv = CommunicationValue::from_json(&json);
Uuid::parse_str(cv.get_data(DataTypes::UserId).unwrap()).ok() Uuid::parse_str(&*cv.get_data(DataTypes::UserId).unwrap().to_string()).ok()
} }
pub async fn complete_register(user_profile: &UserProfile, iota_id: &str) -> bool { pub async fn complete_register(user_profile: &UserProfile, iota_id: &str) -> bool {

View file

@ -286,7 +286,7 @@ pub struct CommunicationValue {
pub log_value: Option<LogValue>, pub log_value: Option<LogValue>,
pub sender: Option<Uuid>, pub sender: Option<Uuid>,
pub receiver: Option<Uuid>, pub receiver: Option<Uuid>,
pub data: HashMap<DataTypes, String>, pub data: HashMap<DataTypes, JsonValue>,
} }
impl CommunicationValue { impl CommunicationValue {
@ -328,11 +328,15 @@ impl CommunicationValue {
pub fn get_receiver(&self) -> Option<Uuid> { pub fn get_receiver(&self) -> Option<Uuid> {
self.receiver.clone() self.receiver.clone()
} }
pub fn add_data(mut self, key: DataTypes, value: String) -> Self { pub fn add_data_str(mut self, key: DataTypes, value: String) -> Self {
self.data.insert(key, JsonValue::String(value));
self
}
pub fn add_data(mut self, key: DataTypes, value: JsonValue) -> Self {
self.data.insert(key, value); self.data.insert(key, value);
self self
} }
pub fn get_data(&mut self, key: DataTypes) -> Option<&String> { pub fn get_data(&mut self, key: DataTypes) -> Option<&JsonValue> {
self.data.get(&key) self.data.get(&key)
} }
@ -376,7 +380,7 @@ impl CommunicationValue {
if parsed["data"].is_object() { if parsed["data"].is_object() {
for (k, v) in parsed["data"].entries() { for (k, v) in parsed["data"].entries() {
if let Some(val) = v.as_str() { if let Some(val) = v.as_str() {
data.insert(DataTypes::parse(k.to_string()), val.to_string()); data.insert(DataTypes::parse(k.to_string()), v.clone());
} }
} }
} }
@ -394,12 +398,12 @@ impl CommunicationValue {
.with_id(message_id); .with_id(message_id);
if let Some(s) = sender { if let Some(s) = sender {
cv = cv.add_data(DataTypes::SenderId, s.to_string()); cv = cv.add_data(DataTypes::SenderId, JsonValue::String(s.to_string()));
} }
cv cv
} }
pub fn forward_to_other_iota(original: &mut CommunicationValue) -> CommunicationValue { pub fn forward_to_other_iota(original: &mut CommunicationValue) -> CommunicationValue {
let receiver = Uuid::from_str(original.get_data(DataTypes::ReceiverId).unwrap()).ok() let receiver = Uuid::from_str(&*original.get_data(DataTypes::ReceiverId).unwrap().to_string()).ok()
.or(Option::from(Uuid::nil())); .or(Option::from(Uuid::nil()));
let now_ms = SystemTime::now() let now_ms = SystemTime::now()
@ -410,12 +414,12 @@ impl CommunicationValue {
let mut cv = CommunicationValue::new(CommunicationType::MessageOtherIota) let mut cv = CommunicationValue::new(CommunicationType::MessageOtherIota)
.with_id(original.get_id()) .with_id(original.get_id())
.with_receiver(receiver.unwrap()) .with_receiver(receiver.unwrap())
.add_data(DataTypes::SendTime, now_ms.to_string()) .add_data(DataTypes::SendTime, JsonValue::String(now_ms.to_string()))
.add_data(DataTypes::MessageContent, original.get_data(DataTypes::MessageContent).unwrap().to_string()); .add_data(DataTypes::MessageContent, JsonValue::String(original.get_data(DataTypes::MessageContent).unwrap().to_string()));
// include sender_id if the original had one // include sender_id if the original had one
if let Some(sender) = original.get_sender() { if let Some(sender) = original.get_sender() {
cv = cv.add_data(DataTypes::SenderId, sender.to_string()); cv = cv.add_data(DataTypes::SenderId, JsonValue::String(sender.to_string()));
} }
cv cv
} }

27
src/eula/eula_checker.rs Normal file
View file

@ -0,0 +1,27 @@
use crate::util::file_util::{load_file, save_file};
pub fn check_eula() -> bool{
let eula = "By changing the value to \"true\" you agree to our end user license agreement and our terms of service!\
\nYou can find our Terms of service on https://docs.tensamin.methanium.net/legal/terms-of-service/.\
\neula=false";
let file = load_file("", "eula.txt");
if(file.is_empty()){
save_file("", "eula.txt", eula);
return false;
}
if (file.contains("eula=false")) {
false
} else if (file.contains("eula=true")) {
true
} else {
false
}
}
pub fn accept_eula(){
let eula = "By changing the value to \"true\" you agree to some shit we say on our website IDK this shouldn't be public yet!\
\nYou also give us all rights to your soul, and we own your dog now.\
\neula=true";
save_file("", "eula.txt", eula);
}

1
src/eula/mod.rs Normal file
View file

@ -0,0 +1 @@
pub mod eula_checker;

View file

@ -1,42 +1,59 @@
use tokio::runtime::Runtime;
use std::process::{Command, ExitStatus};
use futures_util::SinkExt; use futures_util::SinkExt;
use json::{self}; use json::{self, JsonValue};
use json::JsonValue::String;
use uuid::Uuid; use uuid::Uuid;
mod data; mod data;
mod omikron; mod omikron;
mod util; mod util;
mod users; mod users;
mod eula;
mod gui { mod gui {
pub mod ratatui_interface; pub mod ratatui_interface;
} }
mod auth;
mod auth;
use crate::eula::*;
use crate::omikron::omikron_connection::{OmikronConnection}; use crate::omikron::omikron_connection::{OmikronConnection};
use crate::data::communication::{CommunicationValue, CommunicationType, DataTypes}; use crate::data::communication::{CommunicationValue, CommunicationType, DataTypes};
use gui::{ratatui_interface}; use crate::users::user_manager::UserManager;
use crate::util::config_util::ConfigUtil;
#[tokio::main] #[tokio::main]
async fn main() { async fn main() {
let mut omikron: OmikronConnection = OmikronConnection::new(); if(!eula_checker::check_eula()){
println!("Please accept the end user license agreement before launching!");
return;
}
let mut c_util = ConfigUtil::new();
c_util.load();
if !c_util.config.has_key("iota_id") {
c_util.change("iota_id", Uuid::new_v4());
c_util.save();
}
UserManager::load_users().await;
let mut sb = "".to_string();
for up in UserManager::get_users() {
sb = sb + "," + &*up.user_id.to_string();
}
UserManager::save_users();
let omikron: OmikronConnection = OmikronConnection::new();
omikron.connect().await; omikron.connect().await;
omikron.send_message( omikron.send_message(
CommunicationValue::new( CommunicationValue::new(
CommunicationType::Identification CommunicationType::Identification
) )
.add_data(DataTypes::UserIds, Uuid::new_v4().to_string()) .add_data(DataTypes::UserIds, String(sb.to_string()))
.add_data(DataTypes::IotaId, Uuid::new_v4().to_string()) .add_data(DataTypes::IotaId, String(c_util.config["iota_id"].to_string()))
.to_json() .to_json()
.to_string() .to_string()
.as_mut() .as_mut()
.to_string() .to_string()
); ).await;
let mut child = Command::new("sleep").arg("5").spawn().unwrap(); loop {}
let _result = child.wait().unwrap();
omikron.close().await;
println!("reached end of main");
} }

View file

@ -1,9 +1,9 @@
use futures_util::{SinkExt, StreamExt}; use futures_util::{SinkExt, StreamExt};
use std::collections::HashMap; use std::collections::HashMap;
use std::ptr::write;
use std::str::FromStr; use std::str::FromStr;
use std::sync::Arc; use std::sync::Arc;
use std::time::{SystemTime, UNIX_EPOCH}; use std::time::{SystemTime, UNIX_EPOCH};
use json::JsonValue;
use tokio::sync::Mutex; use tokio::sync::Mutex;
use tokio::net::TcpStream; use tokio::net::TcpStream;
use tokio::time::{sleep, Duration}; use tokio::time::{sleep, Duration};
@ -37,7 +37,7 @@ impl OmikronConnection {
} }
/// Connect loop with retry /// Connect loop with retry
pub async fn connect(&self) { pub async fn connect<'a>(&'a self) {
loop { loop {
match connect_async("wss://tensamin.methanium.net/ws/iota/").await { match connect_async("wss://tensamin.methanium.net/ws/iota/").await {
Ok((ws_stream, _)) => { Ok((ws_stream, _)) => {
@ -85,14 +85,6 @@ impl OmikronConnection {
println!("[Omikron] Pong received"); println!("[Omikron] Pong received");
// handle pingpong reset here // handle pingpong reset here
} }
if waiting.lock().await.contains_key(&cv.get_id()) {
if let Some(callback) = waiting.lock().await.remove(&cv.get_id()) {
callback(cv);
}
continue;
}
// ************************************************ // // ************************************************ //
// Direct messages // // Direct messages //
// ************************************************ // // ************************************************ //
@ -100,19 +92,20 @@ impl OmikronConnection {
let sender_id = &cv.get_sender(); let sender_id = &cv.get_sender();
let receiver_id = &cv.get_receiver(); let receiver_id = &cv.get_receiver();
ChatFiles::add_message( ChatFiles::add_message(
cv.get_data(DataTypes::SendTime).unwrap().parse::<i64>().unwrap_or(-1),
cv.get_data(DataTypes::SendTime).unwrap().as_i64().unwrap_or(-1),
false, false,
receiver_id.unwrap(), receiver_id.unwrap(),
sender_id.unwrap(), sender_id.unwrap(),
cv.get_data(DataTypes::MessageContent).unwrap().as_str(), cv.get_data(DataTypes::MessageContent).unwrap().as_str().unwrap(),
); );
let response = CommunicationValue::new(CommunicationType::MessageLive) let response = CommunicationValue::new(CommunicationType::MessageLive)
.with_id(cv.get_id()) .with_id(cv.get_id())
.with_receiver(cv.get_receiver().unwrap()) .with_receiver(cv.get_receiver().unwrap())
.add_data(DataTypes::SendTime, cv.get_data(DataTypes::SendTime).unwrap().to_string()) .add_data(DataTypes::SendTime, cv.get_data(DataTypes::SendTime).unwrap().clone())
.add_data(DataTypes::Message, cv.get_data(DataTypes::MessageContent).unwrap().to_string()) .add_data(DataTypes::Message, cv.get_data(DataTypes::MessageContent).unwrap().clone())
.add_data(DataTypes::SenderId, cv.get_sender().unwrap().to_string()); .add_data(DataTypes::SenderId, JsonValue::String(cv.get_sender().unwrap().clone().to_string()));
Self::send_message_static(&writer, response.to_json().to_string()).await; Self::send_message_static(&writer.clone(), response.to_json().to_string()).await;
continue; continue;
} }
@ -129,10 +122,10 @@ impl OmikronConnection {
); );
// ack // ack
let ack = CommunicationValue::ack_message(cv.get_id(), my_id); let ack = CommunicationValue::ack_message(cv.get_id(), my_id);
Self::send_message_static(&writer, ack.to_json().to_string()).await; Self::send_message_static(&writer.clone(), ack.to_json().to_string()).await;
// forward // forward
let forward = CommunicationValue::forward_to_other_iota(&mut cv); let forward = CommunicationValue::forward_to_other_iota(&mut cv);
Self::send_message_static(&writer, forward.to_json().to_string()).await; Self::send_message_static(&writer.clone(), forward.to_json().to_string()).await;
continue; continue;
} }
@ -147,9 +140,9 @@ impl OmikronConnection {
.with_id(cv.get_id()) .with_id(cv.get_id())
.with_receiver(my_id); .with_receiver(my_id);
if !messages.is_empty() { if !messages.is_empty() {
resp = resp.add_data(DataTypes::MessageChunk, messages.to_string()); resp = resp.add_data(DataTypes::MessageChunk, messages);
} }
Self::send_message_static(&writer, resp.to_json().to_string()).await; Self::send_message_static(&writer.clone(), resp.to_json().to_string()).await;
continue; continue;
} }
@ -159,14 +152,14 @@ impl OmikronConnection {
let resp = CommunicationValue::new(CommunicationType::GetChats) let resp = CommunicationValue::new(CommunicationType::GetChats)
.with_id(cv.get_id()) .with_id(cv.get_id())
.with_receiver(user_id.unwrap()) .with_receiver(user_id.unwrap())
.add_data(DataTypes::UserIds, users.to_string()); .add_data(DataTypes::UserIds, users);
Self::send_message_static(&writer, resp.to_json().to_string()).await; Self::send_message_static(&writer.clone(), resp.to_json().to_string()).await;
continue; continue;
} }
if cv.is_type(CommunicationType::AddChat) { if cv.is_type(CommunicationType::AddChat) {
let user_id = cv.get_sender(); let user_id = cv.get_sender();
let other_id = Uuid::from_str(&*cv.get_data(DataTypes::ReceiverId).unwrap().to_string()).unwrap(); let other_id = Uuid::from_str(&*cv.get_data(DataTypes::UserId).unwrap().to_string()).unwrap();
let mut contact = ChatsUtil::get_user(user_id.unwrap(), other_id).unwrap_or(Contact::new(other_id)); // needs ChatsUtil + Contact let mut contact = ChatsUtil::get_user(user_id.unwrap(), other_id).unwrap_or(Contact::new(other_id)); // needs ChatsUtil + Contact
contact.set_last_message_at(SystemTime::now() contact.set_last_message_at(SystemTime::now()
.duration_since(UNIX_EPOCH) .duration_since(UNIX_EPOCH)
@ -176,7 +169,7 @@ impl OmikronConnection {
let resp = CommunicationValue::new(CommunicationType::AddChat) let resp = CommunicationValue::new(CommunicationType::AddChat)
.with_id(cv.get_id()) .with_id(cv.get_id())
.with_receiver(user_id.unwrap()); .with_receiver(user_id.unwrap());
Self::send_message_static(&writer, resp.to_json().to_string()).await; Self::send_message_static(&writer.clone(), resp.to_json().to_string()).await;
continue; continue;
} }
@ -189,7 +182,7 @@ impl OmikronConnection {
let resp = CommunicationValue::new(CommunicationType::AddCommunity) let resp = CommunicationValue::new(CommunicationType::AddCommunity)
.with_id(cv.get_id()) .with_id(cv.get_id())
.with_receiver(cv.get_sender().unwrap()); .with_receiver(cv.get_sender().unwrap());
Self::send_message_static(&writer, resp.to_json().to_string()).await; Self::send_message_static(&writer.clone(), resp.to_json().to_string()).await;
continue; continue;
} }
@ -197,8 +190,8 @@ impl OmikronConnection {
let resp = CommunicationValue::new(CommunicationType::GetCommunities) let resp = CommunicationValue::new(CommunicationType::GetCommunities)
.with_id(cv.get_id()) .with_id(cv.get_id())
.with_receiver(cv.get_sender().unwrap()) .with_receiver(cv.get_sender().unwrap())
.add_data(DataTypes::Communities, UserCommunityUtil::get_communities(cv.get_sender().unwrap()).to_string()); // needs UserCommunityUtil .add_data(DataTypes::Communities, UserCommunityUtil::get_communities(cv.get_sender().unwrap())); // needs UserCommunityUtil
Self::send_message_static(&writer, resp.to_json().to_string()).await; Self::send_message_static(&writer.clone(), resp.to_json().to_string()).await;
continue; continue;
} }
@ -207,7 +200,7 @@ impl OmikronConnection {
let resp = CommunicationValue::new(CommunicationType::RemoveCommunity) let resp = CommunicationValue::new(CommunicationType::RemoveCommunity)
.with_id(cv.get_id()) .with_id(cv.get_id())
.with_receiver(cv.get_sender().unwrap()); .with_receiver(cv.get_sender().unwrap());
Self::send_message_static(&writer, resp.to_json().to_string()).await; Self::send_message_static(&writer.clone(), resp.to_json().to_string()).await;
continue; continue;
} }
} }
@ -220,16 +213,20 @@ impl OmikronConnection {
} }
}); });
} }
pub fn send_message(&self, msg: String){ pub async fn send_message(&self, msg: String) {
OmikronConnection::send_message_static(&self.writer, msg); Self::send_message_static(&self.writer, msg).await;
} }
pub async fn send_message_static( pub async fn send_message_static(
writer: &Arc<Mutex<Option<futures_util::stream::SplitSink<WebSocketStream<MaybeTlsStream<TcpStream>>, Message>>>>, writer: &Arc<Mutex<Option<futures_util::stream::SplitSink<WebSocketStream<MaybeTlsStream<TcpStream>>, Message>>>>,
msg: String, msg: String,
) { ) -> Result<(), tokio_tungstenite::tungstenite::Error> {
let mut guard = writer.lock().await; let mut guard = writer.lock().await;
if let Some(writer) = guard.as_mut() { if let Some(writer) = guard.as_mut() {
let _ = writer.send(Message::Text(msg)).await; writer.send(Message::Text(msg)).await?;
writer.flush().await?;
Ok(())
} else {
Err(tokio_tungstenite::tungstenite::Error::ConnectionClosed)
} }
} }

View file

@ -1,6 +1,5 @@
use json::{self, JsonValue}; use json::{self, JsonValue};
use std::time::{SystemTime, UNIX_EPOCH}; use std::time::{SystemTime, UNIX_EPOCH};
use axum::Json;
use uuid::Uuid; use uuid::Uuid;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]

View file

@ -10,6 +10,7 @@ use json::{JsonValue};
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use crate::users::user_profile::UserProfile; use crate::users::user_profile::UserProfile;
use crate::users::user_profile_full::UserProfileFull; use crate::users::user_profile_full::UserProfileFull;
use crate::util::file_util::{load_file, save_file};
pub struct UserManager; pub struct UserManager;
@ -72,20 +73,19 @@ impl UserManager {
let users = USERS.lock().unwrap(); let users = USERS.lock().unwrap();
let arr: Vec<JsonValue> = users.iter().map(|u| u.to_json()).collect(); let arr: Vec<JsonValue> = users.iter().map(|u| u.to_json()).collect();
let json_str = JsonValue::Array(arr).dump(); let json_str = JsonValue::Array(arr).dump();
fs::write("users.json", json_str)?;
save_file("", "users.json", &json_str);
Ok(()) Ok(())
} }
pub async fn load_users() -> io::Result<()> { pub async fn load_users() -> io::Result<()> {
let path = Path::new("users.json"); let content = load_file("", "users.json");
if !path.exists() {
return Ok(());
}
let content = fs::read_to_string(path)?;
if content.trim().is_empty() { if content.trim().is_empty() {
return Ok(()); return Ok(());
} }
let parsed = json::parse(&content).map_err(|e| io::Error::new(io::ErrorKind::Other, e.to_string()))?;
let parsed = json::parse(&content)
.map_err(|e| io::Error::new(io::ErrorKind::Other, e.to_string()))?;
if let JsonValue::Array(arr) = parsed { if let JsonValue::Array(arr) = parsed {
let mut users = USERS.lock().unwrap(); let mut users = USERS.lock().unwrap();
for j in arr.iter() { for j in arr.iter() {

View file

@ -2,6 +2,8 @@ use json::JsonValue;
use std::fs::{self, File}; use std::fs::{self, File};
use std::io::{Read, Write}; use std::io::{Read, Write};
use std::path::Path; use std::path::Path;
use uuid::Uuid;
use crate::util::file_util::{load_file, save_file};
pub struct ConfigUtil { pub struct ConfigUtil {
pub config: JsonValue, pub config: JsonValue,
@ -16,37 +18,15 @@ impl ConfigUtil {
} }
} }
fn load_file(path: &str) -> String {
if let Ok(mut f) = File::open(path) {
let mut content = String::new();
let _ = f.read_to_string(&mut content);
content
} else {
String::new()
}
}
fn save_file(path: &str, content: &str) -> std::io::Result<()> {
if let Some(parent) = Path::new(path).parent() {
fs::create_dir_all(parent)?;
}
let mut file = File::create(path)?;
file.write_all(content.as_bytes())
}
pub fn load(&mut self) { pub fn load(&mut self) {
let s = Self::load_file("config.json"); let s = load_file("", "config.json");
if !s.is_empty() { if !s.is_empty() {
self.config = json::parse(&s).unwrap_or(JsonValue::new_object()); self.config = json::parse(&s).unwrap_or(JsonValue::new_object());
} }
if self.config.has_key("ssl_port") {
if let Some(port) = self.config["ssl_port"].as_i32() {
}
}
} }
pub fn change(&mut self, key: &str, value: JsonValue) { pub fn change(&mut self, key: &str, value: Uuid) {
self.config[key] = value; self.config[key] = JsonValue::String(value.to_string());
self.unique = true; self.unique = true;
} }
@ -56,7 +36,7 @@ impl ConfigUtil {
} }
} }
pub fn save(&self) -> std::io::Result<()> { pub fn save(&self) {
Self::save_file("config.json", &self.config.dump()) save_file("","config.json", &self.config.to_string());
} }
} }

View file

@ -8,149 +8,143 @@ use std::process;
use walkdir::WalkDir; use walkdir::WalkDir;
use std::fmt::Write as FmtWrite; use std::fmt::Write as FmtWrite;
use uuid::Uuid; use uuid::Uuid;
pub fn delete_file(path: &str, name: &str) -> bool {
pub struct FileUtil; let dir = Path::new(&get_directory()).join(path);
let file = dir.join(name);
impl FileUtil { if !file.exists() {
pub fn delete_file(path: &str, name: &str) -> bool { return false;
let dir = Path::new(&Self::get_jar_directory()).join(path);
let file = dir.join(name);
if !file.exists() {
return false;
}
fs::remove_file(file).is_ok()
} }
fs::remove_file(file).is_ok()
}
pub fn delete_directory(path: &str) -> bool { pub fn delete_directory(path: &str) -> bool {
let dir = Path::new(&Self::get_jar_directory()).join(path); let dir = Path::new(&get_directory()).join(path);
Self::delete_dir_recursive(&dir) 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) {
fn delete_dir_recursive(directory: &Path) -> bool { println!("[IMPORTANT] Couldn't delete directory {}: {}", directory.display(), e);
if !directory.exists() { return false;
return false;
}
if let Err(e) = fs::remove_dir_all(directory) {
println!("[IMPORTANT] Couldn't delete directory {}: {}", directory.display(), e);
return false;
}
true
} }
true
}
pub fn delete_user_directory(user_id: Uuid) { pub fn delete_user_directory(user_id: Uuid) {
let user_dir = Path::new(&Self::get_jar_directory()) let user_dir = Path::new(&get_directory())
.join("users") .join("users")
.join(user_id.to_string()); .join(user_id.to_string());
let _ = Self::delete_dir_recursive(&user_dir); let _ = delete_dir_recursive(&user_dir);
} }
pub fn load_file(path: &str, name: &str) -> String { pub fn load_file(path: &str, name: &str) -> String {
let dir = Path::new(&Self::get_jar_directory()).join(path); let dir = Path::new(&get_directory()).join(path);
let file_path = dir.join(name); let file_path = dir.join(name);
if !dir.exists() { if !dir.exists() {
if let Err(e) = fs::create_dir_all(&dir) { if let Err(e) = fs::create_dir_all(&dir) {
println!("[IMPORTANT] Couldn't create directories: {}", e); println!("[IMPORTANT] Couldn't create directories: {}", e);
return String::new();
}
return String::new(); 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) { if !file_path.exists() {
let dir = Path::new(&Self::get_jar_directory()).join(path); if let Err(e) = File::create(&file_path) {
let file_path = dir.join(name); println!("[IMPORTANT] Couldn't create file: {}", e);
if !dir.exists() {
if let Err(e) = fs::create_dir_all(&dir) {
println!("[IMPORTANT] Couldn't create directories: {}", e);
return;
}
} }
return String::new();
}
if let Err(e) = fs::write(&file_path, value) { let mut content = String::new();
println!("[IMPORTANT] Couldn't write file {}: {}", file_path.display(), e); 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;
} }
} }
pub fn get_jar_directory() -> String { if let Err(e) = fs::write(&file_path, value) {
// In Rust, use current_exe as a proxy for JAR directory println!("[IMPORTANT] Couldn't write file {}: {}", file_path.display(), e);
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 {
Self::get_directory_size(&PathBuf::from(Self::get_jar_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(&Self::get_jar_directory())
.join("users")
.join(user_id.to_string());
Self::design_byte(Self::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!(
"{}/{}",
Self::design_byte(used),
Self::design_byte(total)
)
} }
} }
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)
)
}