...
This commit is contained in:
parent
05763e7dd3
commit
1ea0b97f6d
49 changed files with 869 additions and 289 deletions
|
|
@ -13,3 +13,15 @@ pnet = "0.35.0"
|
|||
ratatui = "0.30.0"
|
||||
reqwest = "0.13.2"
|
||||
tokio = { version = "1.50.0", features = ["full"] }
|
||||
sysinfo = "0.38.3"
|
||||
uuid = { version = "*", features = ["v4"] }
|
||||
walkdir = "2.5.0"
|
||||
zip = "6.0.0"
|
||||
aes-gcm = "0.10.3"
|
||||
base64 = "0.22.1"
|
||||
rand_core = { version = "0.6", features = ["getrandom", "std"] }
|
||||
sha2 = "0.10.9"
|
||||
x448 = { version = "*" }
|
||||
hkdf = "0.12.4"
|
||||
once_cell = "1.21.3"
|
||||
hex = "*"
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use uuid::Uuid;
|
|||
use walkdir::WalkDir;
|
||||
use zip::ZipArchive;
|
||||
|
||||
use crate::log;
|
||||
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn delete_directory(path: &str) -> bool {
|
||||
|
|
@ -23,7 +23,7 @@ fn delete_dir_recursive(directory: &Path) -> bool {
|
|||
return false;
|
||||
}
|
||||
if let Err(e) = fs::remove_dir_all(directory) {
|
||||
log!(
|
||||
println!(
|
||||
"[IMPORTANT] Couldn't delete directory {}: {}",
|
||||
directory.display(),
|
||||
e,
|
||||
|
|
@ -97,7 +97,7 @@ pub fn load_file(path: &str, name: &str) -> String {
|
|||
|
||||
if !dir.exists() {
|
||||
if let Err(e) = fs::create_dir_all(&dir) {
|
||||
log!("[IMPORTANT] Couldn't create directories: {}", e);
|
||||
println!("[IMPORTANT] Couldn't create directories: {}", e);
|
||||
return String::new();
|
||||
}
|
||||
return String::new();
|
||||
|
|
@ -105,7 +105,7 @@ pub fn load_file(path: &str, name: &str) -> String {
|
|||
|
||||
if !file_path.exists() {
|
||||
if let Err(e) = File::create(&file_path) {
|
||||
log!("[IMPORTANT] Couldn't create file: {}", e);
|
||||
println!("[IMPORTANT] Couldn't create file: {}", e);
|
||||
}
|
||||
return String::new();
|
||||
}
|
||||
|
|
@ -130,13 +130,13 @@ pub fn save_file(path: &str, name: &str, value: &str) {
|
|||
|
||||
if !dir.exists() {
|
||||
if let Err(e) = fs::create_dir_all(&dir) {
|
||||
log!("[IMPORTANT] Couldn't create directories: {}", e);
|
||||
println!("[IMPORTANT] Couldn't create directories: {}", e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if let Err(e) = fs::write(&file_path, value) {
|
||||
log!(
|
||||
println!(
|
||||
"[IMPORTANT] Couldn't write file {}: {}",
|
||||
file_path.display(),
|
||||
e
|
||||
|
|
@ -231,7 +231,7 @@ pub async fn download_zip(url: &str, zip_path: &Path) -> Result<(), Box<dyn std:
|
|||
|
||||
if !response.status().is_success() {
|
||||
let err_msg = format!("Failed to download file: Status {}", response.status());
|
||||
log!("{}", err_msg.clone());
|
||||
println!("{}", err_msg.clone());
|
||||
return Err(err_msg.into());
|
||||
}
|
||||
|
||||
|
|
@ -314,7 +314,7 @@ fn extract_zip_contents_to_folder(
|
|||
}
|
||||
}
|
||||
|
||||
log!("Extracting directly (no single root folder detected).");
|
||||
println!("Extracting directly (no single root folder detected).");
|
||||
let _ = fs::remove_dir_all(target_dir);
|
||||
fs::rename(&staging_dir, target_dir)?;
|
||||
|
||||
|
|
@ -323,14 +323,14 @@ fn extract_zip_contents_to_folder(
|
|||
|
||||
#[allow(dead_code)]
|
||||
pub async fn download_and_extract_zip(url: &str, as_name: &str) {
|
||||
log!("Downloading ZIP file...");
|
||||
println!("Downloading ZIP file...");
|
||||
let base_dir = PathBuf::from(get_directory());
|
||||
let zip_filename = format!("{}.zip", Uuid::new_v4());
|
||||
let zip_path = base_dir.join(&zip_filename);
|
||||
let target_dir = base_dir.join(as_name);
|
||||
|
||||
if let Err(e) = download_zip(url, &zip_path).await {
|
||||
log!("Error downloading file: {}", e);
|
||||
println!("Error downloading file: {}", e);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -341,14 +341,14 @@ pub async fn download_and_extract_zip(url: &str, as_name: &str) {
|
|||
let successful = match extract_result {
|
||||
Ok(()) => true,
|
||||
Err(e) => {
|
||||
log!("Error during ZIP extraction: {}", e);
|
||||
println!("Error during ZIP extraction: {}", e);
|
||||
false
|
||||
}
|
||||
};
|
||||
|
||||
if let Err(e) = tokio::fs::remove_file(&zip_path).await {
|
||||
log!("Error cleaning up ZIP file {}: {}", zip_path.display(), e);
|
||||
println!("Error cleaning up ZIP file {}: {}", zip_path.display(), e);
|
||||
} else if successful {
|
||||
log!("Downloaded and extracted ZIP file successfully.");
|
||||
println!("Downloaded and extracted ZIP file successfully.");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
80
iota-util/src/langu/language_creator.rs
Normal file
80
iota-util/src/langu/language_creator.rs
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
use crate::file_util::save_file;
|
||||
use json::{self, JsonError, JsonValue};
|
||||
|
||||
pub fn create_languages() -> Result<(), JsonError> {
|
||||
let mut frontend_messages = JsonValue::new_object();
|
||||
let mut omikron_messages = JsonValue::new_object();
|
||||
let mut button_texts = JsonValue::new_object();
|
||||
let mut general_texts = JsonValue::new_object();
|
||||
let mut debug_messages = JsonValue::new_object();
|
||||
|
||||
frontend_messages.insert("error", "An error occurred")?;
|
||||
// FRONTEND
|
||||
frontend_messages.insert("get_chats", "User {} is loading conversations")?;
|
||||
frontend_messages.insert("message_get", "User {} is loading messages")?;
|
||||
frontend_messages.insert("get_communities", "User {} is loading communities")?;
|
||||
frontend_messages.insert("client_connected", "Client {} connected")?;
|
||||
frontend_messages.insert("add_conversation", "User {} added {}")?;
|
||||
frontend_messages.insert("message_send", "User {} sent a message")?;
|
||||
|
||||
// OMIKRON
|
||||
omikron_messages.insert(
|
||||
"identification_response",
|
||||
"IOTA identified on Omikron, {} users!",
|
||||
)?;
|
||||
omikron_messages.insert(
|
||||
"send_message_failed",
|
||||
"Failed to send message to Omikron: {}",
|
||||
)?;
|
||||
omikron_messages.insert("connection_failed", "Failed to connect to Omikron: {}")?;
|
||||
|
||||
// BUTTONS
|
||||
button_texts.insert("exit", "Exit")?;
|
||||
|
||||
// GENERAL
|
||||
general_texts.insert("iota_id", "IOTA ID: {}-####-####-####-############")?;
|
||||
general_texts.insert("user_id", "USER ID: {}")?;
|
||||
general_texts.insert("user_ids", "USER IDS: {}")?;
|
||||
general_texts.insert("user_load_failed", "Failed to load user data")?;
|
||||
general_texts.insert("setup_completed", "Launched")?;
|
||||
general_texts.insert(
|
||||
"community_active",
|
||||
"Communities active on ws://{}:{}/community/...",
|
||||
)?;
|
||||
general_texts.insert(
|
||||
"community_start_error",
|
||||
"Failed to start community socket on port {}!",
|
||||
)?;
|
||||
general_texts.insert(
|
||||
"community_start_error_admin",
|
||||
"Failed to start community socket on port {}! Run with admin privileges",
|
||||
)?;
|
||||
// DEBUG
|
||||
debug_messages.insert("", "")?;
|
||||
save_file(
|
||||
"languages/en_INT",
|
||||
"frontend.json",
|
||||
&frontend_messages.to_string(),
|
||||
);
|
||||
save_file(
|
||||
"languages/en_INT",
|
||||
"omikron.json",
|
||||
&omikron_messages.to_string(),
|
||||
);
|
||||
save_file(
|
||||
"languages/en_INT",
|
||||
"buttons.json",
|
||||
&button_texts.to_string(),
|
||||
);
|
||||
save_file(
|
||||
"languages/en_INT",
|
||||
"debug.json",
|
||||
&debug_messages.to_string(),
|
||||
);
|
||||
save_file(
|
||||
"languages/en_INT",
|
||||
"general.json",
|
||||
&general_texts.to_string(),
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
105
iota-util/src/langu/language_manager.rs
Normal file
105
iota-util/src/langu/language_manager.rs
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
use crate::file_util::{self};
|
||||
use json::parse;
|
||||
use once_cell::sync::Lazy;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Mutex;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct LanguagePack {
|
||||
language: HashMap<String, String>,
|
||||
}
|
||||
|
||||
pub static LANGUAGE_PACK: Lazy<Mutex<LanguagePack>> =
|
||||
Lazy::new(|| Mutex::new(LanguagePack::new("en_INT")));
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn get_language() -> LanguagePack {
|
||||
LANGUAGE_PACK.lock().unwrap().clone()
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn get_languages() -> Vec<String> {
|
||||
file_util::get_children("languages")
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn set_language(language: &str) {
|
||||
LANGUAGE_PACK.lock().unwrap().language.clear();
|
||||
LANGUAGE_PACK.lock().unwrap().load_language(language);
|
||||
}
|
||||
|
||||
pub fn from_key(key: &str) -> String {
|
||||
LANGUAGE_PACK
|
||||
.lock()
|
||||
.unwrap()
|
||||
.get_translation(key)
|
||||
.to_string()
|
||||
}
|
||||
|
||||
pub fn format(key: &str, args: &[&str]) -> String {
|
||||
let message = from_key(key);
|
||||
let mut formatted = String::new();
|
||||
let parts = message.split("{}");
|
||||
for (i, part) in parts.enumerate() {
|
||||
formatted.push_str(part);
|
||||
if i < args.len() {
|
||||
formatted.push_str(args[i]);
|
||||
}
|
||||
}
|
||||
formatted
|
||||
}
|
||||
|
||||
impl LanguagePack {
|
||||
pub fn new(language: &str) -> Self {
|
||||
let mut pack = LanguagePack {
|
||||
language: HashMap::new(),
|
||||
};
|
||||
pack.load_language(language);
|
||||
pack
|
||||
}
|
||||
|
||||
pub fn load_language(&mut self, language: &str) {
|
||||
let path = format!("languages/{}/", language);
|
||||
|
||||
let frontend_messages = file_util::load_file(&path, "frontend.json");
|
||||
let frontend_messages = parse(&frontend_messages).unwrap();
|
||||
for (key, value) in frontend_messages.entries() {
|
||||
self.language
|
||||
.insert(key.to_string(), value.as_str().unwrap().to_string());
|
||||
}
|
||||
|
||||
let omikron_messages = file_util::load_file(&path, "omikron.json");
|
||||
let omikron_messages = parse(&omikron_messages).unwrap();
|
||||
for (key, value) in omikron_messages.entries() {
|
||||
self.language
|
||||
.insert(key.to_string(), value.as_str().unwrap().to_string());
|
||||
}
|
||||
|
||||
let button_texts = file_util::load_file(&path, "buttons.json");
|
||||
let button_texts = parse(&button_texts).unwrap();
|
||||
for (key, value) in button_texts.entries() {
|
||||
self.language
|
||||
.insert(key.to_string(), value.as_str().unwrap().to_string());
|
||||
}
|
||||
|
||||
let debug_messages = file_util::load_file(&path, "debug.json");
|
||||
let debug_messages = parse(&debug_messages).unwrap();
|
||||
for (key, value) in debug_messages.entries() {
|
||||
self.language
|
||||
.insert(key.to_string(), value.as_str().unwrap().to_string());
|
||||
}
|
||||
|
||||
let general_messages = file_util::load_file(&path, "general.json");
|
||||
let general_messages = parse(&general_messages).unwrap();
|
||||
for (key, value) in general_messages.entries() {
|
||||
self.language
|
||||
.insert(key.to_string(), value.as_str().unwrap().to_string());
|
||||
}
|
||||
}
|
||||
pub fn get_translation(&self, key: &str) -> String {
|
||||
match self.language.get(key) {
|
||||
Some(v) if !v.is_empty() => v.clone(),
|
||||
_ => key.to_uppercase(),
|
||||
}
|
||||
}
|
||||
}
|
||||
2
iota-util/src/langu/mod.rs
Normal file
2
iota-util/src/langu/mod.rs
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
pub mod language_creator;
|
||||
pub mod language_manager;
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
pub mod crypto_helper;
|
||||
pub mod crypto_util;
|
||||
pub mod file_util;
|
||||
pub mod langu;
|
||||
Loading…
Reference in a new issue