version a0.0.1
This commit is contained in:
commit
9469ef10b6
19 files changed
+4281
No files matched your search
+119
@@ -0,0 +1,119 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{
|
||||
collections::{HashMap, VecDeque},
|
||||
sync::{Arc, RwLock},
|
||||
time::{SystemTime, UNIX_EPOCH},
|
||||
};
|
||||
|
||||
pub const MAX_PAYLOAD_SIZE: usize = 200 * 1024 * 1024;
|
||||
pub const MAX_RAM_TEXTS: usize = 50;
|
||||
pub const MEDIA_DIR: &str = "received_media";
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub struct TextItem {
|
||||
pub sender: String,
|
||||
pub text: String,
|
||||
pub timestamp: u64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub struct MediaItem {
|
||||
pub sender: String,
|
||||
pub filename: String,
|
||||
pub saved_path: String,
|
||||
pub mime: String,
|
||||
pub size: usize,
|
||||
pub timestamp: u64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub struct PeerNode {
|
||||
pub name: String,
|
||||
pub ip: String,
|
||||
pub port: u16,
|
||||
pub fingerprint: String,
|
||||
pub pin_code: String,
|
||||
pub verified: bool,
|
||||
}
|
||||
|
||||
pub struct AppState {
|
||||
pub device_name: String,
|
||||
pub my_ip: String,
|
||||
pub p2p_port: u16,
|
||||
pub my_fingerprint: String,
|
||||
pub ram_texts: RwLock<VecDeque<TextItem>>,
|
||||
pub disk_media: RwLock<VecDeque<MediaItem>>,
|
||||
pub peers: RwLock<HashMap<String, PeerNode>>,
|
||||
pub trusted_fingerprints: Arc<RwLock<HashMap<String, String>>>,
|
||||
pub http_client: reqwest::Client,
|
||||
pub probe_client: reqwest::Client,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct IncomingTextPayload {
|
||||
pub sender: String,
|
||||
pub text: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct UiSendTextRequest {
|
||||
pub target_ip: String,
|
||||
pub text: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct UiTrustRequest {
|
||||
pub target_ip: String,
|
||||
pub trust: bool,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct UiManualPeerRequest {
|
||||
pub ip: String,
|
||||
pub port: Option<u16>,
|
||||
}
|
||||
|
||||
pub fn now_sec() -> u64 {
|
||||
SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap_or_default()
|
||||
.as_secs()
|
||||
}
|
||||
|
||||
pub fn url_decode(input: &str) -> String {
|
||||
let mut bytes = Vec::with_capacity(input.len());
|
||||
let mut chars = input.as_bytes().iter().copied();
|
||||
while let Some(b) = chars.next() {
|
||||
if b == b'%' {
|
||||
if let (Some(c1), Some(c2)) = (chars.next(), chars.next()) {
|
||||
if let Ok(decoded) = u8::from_str_radix(&format!("{}{}", c1 as char, c2 as char), 16)
|
||||
{
|
||||
bytes.push(decoded);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} else if b == b'+' {
|
||||
bytes.push(b' ');
|
||||
} else {
|
||||
bytes.push(b);
|
||||
}
|
||||
}
|
||||
String::from_utf8_lossy(&bytes).into_owned()
|
||||
}
|
||||
|
||||
pub fn sanitize_filename(name: &str) -> String {
|
||||
let decoded = url_decode(name);
|
||||
let clean: String = decoded
|
||||
.chars()
|
||||
.map(|c| match c {
|
||||
'/' | '\\' | ':' | '*' | '?' | '"' | '<' | '>' | '|' | '\0' => '_',
|
||||
_ => c,
|
||||
})
|
||||
.collect();
|
||||
let trimmed = clean.trim_matches('.').trim();
|
||||
if trimmed.is_empty() {
|
||||
"media_file.bin".to_string()
|
||||
} else {
|
||||
trimmed.to_string()
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user