Communities
This commit is contained in:
parent
6ae6e85b5a
commit
1c08956387
26 changed files with 1988 additions and 338 deletions
|
|
@ -1,14 +1,10 @@
|
|||
use crate::util::file_util::{get_children, load_file, save_file};
|
||||
use json::{self, JsonValue, array, object};
|
||||
use sha2::digest::typenum::Add1;
|
||||
use std::fs::{self, File};
|
||||
use std::io::{Read, Write};
|
||||
use std::fs::{self};
|
||||
use std::path::Path;
|
||||
use sys_info::loadavg;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::gui::log_panel::log_message;
|
||||
use crate::langu::language_manager::format;
|
||||
|
||||
pub enum MessageState {
|
||||
Read,
|
||||
|
|
@ -28,172 +24,168 @@ impl MessageState {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct ChatFiles;
|
||||
pub fn add_message(
|
||||
send_time: u128,
|
||||
storage_owner_is_sender: bool,
|
||||
storage_owner: Uuid,
|
||||
external_user: Uuid,
|
||||
message: &str,
|
||||
) {
|
||||
let user_dir = format!("users/{}/chats/{}", storage_owner, external_user);
|
||||
|
||||
impl ChatFiles {
|
||||
pub fn add_message(
|
||||
send_time: i64,
|
||||
storage_owner_is_sender: bool,
|
||||
storage_owner: Uuid,
|
||||
external_user: Uuid,
|
||||
message: &str,
|
||||
) {
|
||||
let user_dir = format!("users/{}/chats/{}", storage_owner, external_user);
|
||||
if let Err(e) = fs::create_dir_all(&user_dir) {
|
||||
log_message(format!("Failed to create chat directory: {}", e));
|
||||
return;
|
||||
}
|
||||
|
||||
if let Err(e) = fs::create_dir_all(&user_dir) {
|
||||
log_message(format!("Failed to create chat directory: {}", e));
|
||||
return;
|
||||
}
|
||||
let mut chunk_index = 0;
|
||||
let mut message_chunk = array![];
|
||||
|
||||
let mut chunk_index = 0;
|
||||
let mut message_chunk = array![];
|
||||
// find latest chunk not full (max 800 msgs)
|
||||
loop {
|
||||
let file_name = format!("msgs_{}.json", chunk_index);
|
||||
let file_content = load_file(&user_dir, &file_name);
|
||||
|
||||
// find latest chunk not full (max 800 msgs)
|
||||
loop {
|
||||
let file_name = format!("msgs_{}.json", chunk_index);
|
||||
let file_content = load_file(&user_dir, &file_name);
|
||||
|
||||
if !file_content.is_empty() {
|
||||
if let Ok(current_chunk) = json::parse(&file_content) {
|
||||
if current_chunk.is_array() && current_chunk.len() < 800 {
|
||||
message_chunk = current_chunk;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
log_message(format!("Failed to parse existing JSON file: {}", file_name));
|
||||
if !file_content.is_empty() {
|
||||
if let Ok(current_chunk) = json::parse(&file_content) {
|
||||
if current_chunk.is_array() && current_chunk.len() < 800 {
|
||||
message_chunk = current_chunk;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// New file, use empty array
|
||||
break;
|
||||
}
|
||||
|
||||
chunk_index += 1;
|
||||
if chunk_index > 1000 {
|
||||
log_message(format!("Too many message chunks. Aborting add."));
|
||||
return;
|
||||
log_message(format!("Failed to parse existing JSON file: {}", file_name));
|
||||
}
|
||||
} else {
|
||||
// New file, use empty array
|
||||
break;
|
||||
}
|
||||
|
||||
let json_obj = object! {
|
||||
"message_time" => send_time,
|
||||
"message_content" => message,
|
||||
"sender_is_me" => storage_owner_is_sender,
|
||||
"message_state" => MessageState::Sending.as_str()
|
||||
};
|
||||
|
||||
if let Err(e) = message_chunk.push(json_obj) {
|
||||
log_message(format!("Failed to push new message into JSON array: {}", e));
|
||||
chunk_index += 1;
|
||||
if chunk_index > 1000 {
|
||||
log_message(format!("Too many message chunks. Aborting add."));
|
||||
return;
|
||||
}
|
||||
|
||||
let file_name = format!("msgs_{}.json", chunk_index);
|
||||
log_message(format!("Saving message to {}/{}", user_dir, file_name));
|
||||
save_file(&user_dir, &file_name, &message_chunk.dump());
|
||||
}
|
||||
pub fn change_message_state(
|
||||
storage_owner: Uuid,
|
||||
external_user: Uuid,
|
||||
timestamp: i64,
|
||||
new_state: MessageState,
|
||||
) -> std::io::Result<()> {
|
||||
let user_dir = format!("users/{}/chats/{}", storage_owner, external_user);
|
||||
let path = Path::new(&user_dir);
|
||||
|
||||
if !path.exists() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let entries = fs::read_dir(path)?;
|
||||
for entry in entries {
|
||||
let entry = entry?;
|
||||
let fname = entry.file_name();
|
||||
let fname_str = fname.to_string_lossy();
|
||||
|
||||
if fname_str.starts_with("msgs_") && fname_str.ends_with(".json") {
|
||||
let file_content = load_file(&user_dir, &fname_str);
|
||||
if file_content.is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Ok(mut chunk) = json::parse(&file_content) {
|
||||
let mut modified = false;
|
||||
for i in 0..chunk.len() {
|
||||
if chunk[i]["message_time"].as_i64() == Some(timestamp) {
|
||||
chunk[i]["message_state"] = JsonValue::from(new_state.as_str());
|
||||
modified = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if modified {
|
||||
save_file(&user_dir, &fname_str, &chunk.dump());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_messages(
|
||||
storage_owner: Uuid,
|
||||
external_user: Uuid,
|
||||
loaded_messages: i64,
|
||||
amount: i64,
|
||||
) -> JsonValue {
|
||||
let mut messages = array![];
|
||||
let json_obj = object! {
|
||||
"timestamp" => send_time as i64,
|
||||
"content" => message,
|
||||
"sent_by_self" => storage_owner_is_sender,
|
||||
"message_state" => MessageState::Sending.as_str()
|
||||
};
|
||||
|
||||
let mut latest_chunk_index: i32 = -1;
|
||||
let files = get_children(&format!("users/{}/chats/{}", storage_owner, external_user));
|
||||
if let Err(e) = message_chunk.push(json_obj) {
|
||||
log_message(format!("Failed to push new message into JSON array: {}", e));
|
||||
return;
|
||||
}
|
||||
|
||||
for entry in files {
|
||||
if let Some(num) = {
|
||||
entry
|
||||
.strip_prefix("msgs_")
|
||||
.and_then(|s| s.strip_suffix(".json"))
|
||||
} {
|
||||
if let Ok(index) = num.parse::<i32>() {
|
||||
if index > latest_chunk_index {
|
||||
latest_chunk_index = index;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let file_name = format!("msgs_{}.json", chunk_index);
|
||||
log_message(format!("Saving message to {}/{}", user_dir, file_name));
|
||||
save_file(&user_dir, &file_name, &message_chunk.dump());
|
||||
}
|
||||
pub fn change_message_state(
|
||||
storage_owner: Uuid,
|
||||
external_user: Uuid,
|
||||
timestamp: i64,
|
||||
new_state: MessageState,
|
||||
) -> std::io::Result<()> {
|
||||
let user_dir = format!("users/{}/chats/{}", storage_owner, external_user);
|
||||
let path = Path::new(&user_dir);
|
||||
|
||||
if latest_chunk_index == -1 {
|
||||
return messages;
|
||||
}
|
||||
if !path.exists() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let mut to_skip = loaded_messages;
|
||||
let mut needed = amount;
|
||||
let entries = fs::read_dir(path)?;
|
||||
for entry in entries {
|
||||
let entry = entry?;
|
||||
let fname = entry.file_name();
|
||||
let fname_str = fname.to_string_lossy();
|
||||
|
||||
for chunk_index in (0..=latest_chunk_index).rev() {
|
||||
if needed == 0 {
|
||||
break;
|
||||
}
|
||||
let file_name = format!("msgs_{}.json", chunk_index);
|
||||
let file_content = load_file(
|
||||
&format!("users/{}/chats/{}", storage_owner, external_user),
|
||||
&file_name,
|
||||
);
|
||||
if fname_str.starts_with("msgs_") && fname_str.ends_with(".json") {
|
||||
let file_content = load_file(&user_dir, &fname_str);
|
||||
if file_content.is_empty() {
|
||||
continue;
|
||||
}
|
||||
if let Ok(chunk) = json::parse(&file_content) {
|
||||
for i in (0..chunk.len()).rev() {
|
||||
if needed == 0 {
|
||||
|
||||
if let Ok(mut chunk) = json::parse(&file_content) {
|
||||
let mut modified = false;
|
||||
for i in 0..chunk.len() {
|
||||
if chunk[i]["message_time"].as_i64() == Some(timestamp) {
|
||||
chunk[i]["message_state"] = JsonValue::from(new_state.as_str());
|
||||
modified = true;
|
||||
break;
|
||||
}
|
||||
if to_skip > 0 {
|
||||
to_skip -= 1;
|
||||
continue;
|
||||
}
|
||||
messages.push(chunk[i].clone()).unwrap();
|
||||
needed -= 1;
|
||||
}
|
||||
|
||||
if modified {
|
||||
save_file(&user_dir, &fname_str, &chunk.dump());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
messages
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_messages(
|
||||
storage_owner: Uuid,
|
||||
external_user: Uuid,
|
||||
loaded_messages: i64,
|
||||
amount: i64,
|
||||
) -> JsonValue {
|
||||
let mut messages = array![];
|
||||
|
||||
let mut latest_chunk_index: i32 = -1;
|
||||
let files = get_children(&format!("users/{}/chats/{}", storage_owner, external_user));
|
||||
|
||||
for entry in files {
|
||||
if let Some(num) = {
|
||||
entry
|
||||
.strip_prefix("msgs_")
|
||||
.and_then(|s| s.strip_suffix(".json"))
|
||||
} {
|
||||
if let Ok(index) = num.parse::<i32>() {
|
||||
if index > latest_chunk_index {
|
||||
latest_chunk_index = index;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if latest_chunk_index == -1 {
|
||||
return messages;
|
||||
}
|
||||
|
||||
let mut to_skip = loaded_messages;
|
||||
let mut needed = amount;
|
||||
|
||||
for chunk_index in (0..=latest_chunk_index).rev() {
|
||||
if needed == 0 {
|
||||
break;
|
||||
}
|
||||
let file_name = format!("msgs_{}.json", chunk_index);
|
||||
let file_content = load_file(
|
||||
&format!("users/{}/chats/{}", storage_owner, external_user),
|
||||
&file_name,
|
||||
);
|
||||
if file_content.is_empty() {
|
||||
continue;
|
||||
}
|
||||
if let Ok(chunk) = json::parse(&file_content) {
|
||||
for i in (0..chunk.len()).rev() {
|
||||
if needed == 0 {
|
||||
break;
|
||||
}
|
||||
if to_skip > 0 {
|
||||
to_skip -= 1;
|
||||
continue;
|
||||
}
|
||||
messages.push(chunk[i].clone()).unwrap();
|
||||
needed -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
messages
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,4 @@
|
|||
use axum::Json;
|
||||
use json::{self, JsonValue, array};
|
||||
use std::path::Path;
|
||||
use std::string::String;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::users::contact::Contact;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
use crate::util::file_util::{load_file, save_file};
|
||||
use json::JsonValue;
|
||||
use once_cell::sync::Lazy;
|
||||
use std::fs::{self, File};
|
||||
use std::path::Path;
|
||||
use std::sync::Mutex;
|
||||
use uuid::Uuid;
|
||||
|
||||
|
|
@ -36,6 +34,10 @@ impl ConfigUtil {
|
|||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
pub fn get_port(&self) -> u16 {
|
||||
self.config["port"].as_u16().unwrap_or(1984)
|
||||
}
|
||||
|
||||
pub fn change(&mut self, key: &str, value: Uuid) {
|
||||
self.config[key] = JsonValue::String(value.to_string());
|
||||
self.unique = true;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,7 @@
|
|||
use std::ffi::OsStr;
|
||||
use std::fmt::Write as FmtWrite;
|
||||
use std::fs::{self, File};
|
||||
use std::io::{Read, Write};
|
||||
use std::io::Read;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process;
|
||||
use std::time::SystemTime;
|
||||
use sysinfo::System;
|
||||
use uuid::Uuid;
|
||||
use walkdir::WalkDir;
|
||||
|
|
|
|||
Loading…
Reference in a new issue