Skip to content

Commit

Permalink
Add: Get Network Info
Browse files Browse the repository at this point in the history
  • Loading branch information
shm11C3 committed Dec 23, 2024
1 parent 5dc4154 commit 1238dbe
Show file tree
Hide file tree
Showing 9 changed files with 160 additions and 3 deletions.
11 changes: 11 additions & 0 deletions src-tauri/src/commands/hardware.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use crate::enums::error::BackendError;
use crate::services::directx_gpu_service;
use crate::services::nvidia_gpu_service;
use crate::services::system_info_service;
use crate::services::wmi_service;
use crate::structs::hardware::NetworkInfo;
use crate::structs::hardware::{GraphicInfo, MemoryInfo, StorageInfo};
use crate::{log_error, log_internal};
use serde::{Deserialize, Serialize, Serializer};
Expand Down Expand Up @@ -314,6 +316,15 @@ pub fn get_gpu_usage_history(
.collect()
}

///
/// ## ネットワーク情報を取得
///
#[command]
#[specta::specta]
pub fn get_network_info() -> Result<Vec<NetworkInfo>, BackendError> {
system_info_service::get_network_info()
}

///
/// ## システム情報の初期化
///
Expand Down
32 changes: 32 additions & 0 deletions src-tauri/src/enums/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use serde::{Serialize, Serializer};
use specta::Type;

#[derive(Debug, PartialEq, Eq, Clone, Type)]
#[serde(rename_all = "camelCase")]
pub enum BackendError {
CpuInfoNotAvailable,
StorageInfoNotAvailable,
MemoryInfoNotAvailable,
GraphicInfoNotAvailable,
NetworkInfoNotAvailable,
NetworkUsageNotAvailable,
// SystemError(String),
}

impl Serialize for BackendError {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let s = match *self {
BackendError::CpuInfoNotAvailable => "cpuInfoNotAvailable",
BackendError::StorageInfoNotAvailable => "storageInfoNotAvailable",
BackendError::MemoryInfoNotAvailable => "memoryInfoNotAvailable",
BackendError::GraphicInfoNotAvailable => "graphicInfoNotAvailable",
BackendError::NetworkInfoNotAvailable => "networkInfoNotAvailable",
BackendError::NetworkUsageNotAvailable => "networkUsageNotAvailable",
// BackendError::SystemError(ref e) => e,
};
serializer.serialize_str(s)
}
}
1 change: 1 addition & 0 deletions src-tauri/src/enums/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pub mod config;
pub mod error;
pub mod hardware;
1 change: 1 addition & 0 deletions src-tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ pub fn run() {
hardware::get_cpu_usage_history,
hardware::get_memory_usage_history,
hardware::get_gpu_usage_history,
hardware::get_network_info,
config::commands::get_settings,
config::commands::set_language,
config::commands::set_theme,
Expand Down
36 changes: 35 additions & 1 deletion src-tauri/src/services/system_info_service.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
use crate::enums;
use crate::enums::error::BackendError;
use crate::structs;
use crate::structs::hardware::NetworkInfo;
use crate::utils;
use crate::utils::formatter::SizeUnit;

use serde::{Deserialize, Serialize};
use specta::Type;
use std::sync::MutexGuard;
use sysinfo::{Disks, System};
use sysinfo::{Disks, IpNetwork, NetworkData, Networks, System};

#[derive(Serialize, Deserialize, Type)]
#[serde(rename_all = "camelCase")]
Expand Down Expand Up @@ -73,3 +75,35 @@ pub fn get_storage_info() -> Result<Vec<structs::hardware::StorageInfo>, String>

Ok(storage_info)
}

pub fn get_network_info() -> Result<Vec<NetworkInfo>, BackendError> {
let interfaces = Networks::new_with_refreshed_list();

if interfaces.is_empty() {
return Err(BackendError::NetworkInfoNotAvailable);
}

let network_info = interfaces
.values()
.map(|interface| {
let ip_networks = interface.ip_networks();
let mac = interface.mac_address();

// IPv4とIPv6を分ける
let (ipv4, ipv6): (Vec<_>, Vec<_>) = ip_networks
.iter()
.partition(|ip_network| ip_network.addr.is_ipv4());

Ok(NetworkInfo {
ipv4: ipv4
.into_iter()
.map(|ip: &IpNetwork| ip.addr.to_string())
.collect(),
ipv6: ipv6.into_iter().map(|ip| ip.addr.to_string()).collect(),
mac: mac.to_string(),
})
})
.collect::<Result<Vec<_>, _>>()?;

Ok(network_info)
}
18 changes: 18 additions & 0 deletions src-tauri/src/structs/hardware.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,21 @@ pub struct StorageInfo {
pub storage_type: DiskKind,
pub file_system: String,
}

#[derive(Serialize, Deserialize, Type)]
#[serde(rename_all = "camelCase")]
pub struct NetworkInfo {
pub ipv4: Vec<String>,
pub ipv6: Vec<String>,
pub mac: String,
}

#[derive(Serialize, Deserialize, Type)]
#[serde(rename_all = "camelCase")]
pub struct NetworkUsage {
pub ip: String,
pub sent: f32,
pub sent_unit: SizeUnit,
pub received: f32,
pub received_unit: SizeUnit,
}
18 changes: 16 additions & 2 deletions src/atom/useHardwareInfoAtom.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useTauriDialog } from "@/hooks/useTauriDialog";
import { type SysInfo, commands } from "@/rspc/bindings";
import { type NetworkInfo, type SysInfo, commands } from "@/rspc/bindings";
import { isError } from "@/types/result";
import { atom, useAtom } from "jotai";

Expand All @@ -10,8 +10,11 @@ const hardInfoAtom = atom<SysInfo>({
storage: [],
});

const networkInfoAtom = atom<NetworkInfo[]>([]);

export const useHardwareInfoAtom = () => {
const [hardwareInfo, setHardInfo] = useAtom(hardInfoAtom);
const [networkInfo, setNetworkInfo] = useAtom(networkInfoAtom);
const { error } = useTauriDialog();

const init = async () => {
Expand All @@ -25,5 +28,16 @@ export const useHardwareInfoAtom = () => {
setHardInfo(fetchedHardwareInfo.data);
};

return { hardwareInfo, init };
const initNetwork = async () => {
const fetchedNetworkInfo = await commands.getNetworkInfo();
if (isError(fetchedNetworkInfo)) {
error(fetchedNetworkInfo.error);
console.error("Failed to fetch network info:", fetchedNetworkInfo);
return;
}

setNetworkInfo(fetchedNetworkInfo.data);
};

return { hardwareInfo, networkInfo, init, initNetwork };
};
14 changes: 14 additions & 0 deletions src/rspc/bindings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,18 @@ async getMemoryUsageHistory(seconds: number) : Promise<number[]> {
async getGpuUsageHistory(seconds: number) : Promise<number[]> {
return await TAURI_INVOKE("get_gpu_usage_history", { seconds });
},
/**
* ## ネットワーク情報を取得
*
*/
async getNetworkInfo() : Promise<Result<NetworkInfo[], BackendError>> {
try {
return { status: "ok", data: await TAURI_INVOKE("get_network_info") };
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async getSettings() : Promise<Result<ClientSettings, string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("get_settings") };
Expand Down Expand Up @@ -292,6 +304,7 @@ async setDecoration(isDecorated: boolean) : Promise<void> {

/** user-defined types **/

export type BackendError = "cpuInfoNotAvailable" | "storageInfoNotAvailable" | "memoryInfoNotAvailable" | "graphicInfoNotAvailable" | "networkInfoNotAvailable" | "networkUsageNotAvailable"
/**
* - `file_id` : 画像ファイルID
* - `image_data` : 画像データのBase64文字列
Expand All @@ -311,6 +324,7 @@ export type HardwareType = "cpu" | "memory" | "gpu"
export type LineGraphColorStringSettings = { cpu: string; memory: string; gpu: string }
export type MemoryInfo = { size: string; clock: number; clockUnit: string; memoryCount: number; totalSlots: number; memoryType: string }
export type NameValue = { name: string; value: number }
export type NetworkInfo = { ipv4: string[]; ipv6: string[]; mac: string }
export type ProcessInfo = { pid: number; name: string; cpuUsage: number; memoryUsage: number }
export type SizeUnit = "B" | "KB" | "MB" | "GB"
export type StorageInfo = { name: string; size: number; sizeUnit: SizeUnit; free: number; freeUnit: SizeUnit; storageType: DiskKind; fileSystem: string }
Expand Down
32 changes: 32 additions & 0 deletions src/template/Dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,34 @@ const StorageDataInfo = () => {
);
};

const NetworkInfo = () => {
const { t } = useTranslation();

Check failure on line 229 in src/template/Dashboard.tsx

View workflow job for this annotation

GitHub Actions / test-tauri (windows-latest)

't' is declared but its value is never read.
const { networkInfo, initNetwork } = useHardwareInfoAtom();

// biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>
useEffect(() => {
initNetwork();
}, []);

return (
<>
{networkInfo.map((network) => {
return (
<div key={network.mac} className="mt-4">
<InfoTable
data={{
ipv4: network.ipv4.join(", "),
ipv6: network.ipv6.join(", "),
mac: network.mac,
}}
/>
</div>
);
})}
</>
);
};

const Dashboard = () => {
const { hardwareInfo } = useHardwareInfoAtom();
const { init } = useHardwareInfoAtom();
Expand Down Expand Up @@ -252,6 +280,10 @@ const Dashboard = () => {
key: "processesTable",
component: <ProcessesTable />,
},
{
key: "networkInfo",
component: <NetworkInfo />,
},
].filter((x) => x != null);

const dataAreaKey2Title: Record<string, string> = {
Expand Down

0 comments on commit 1238dbe

Please sign in to comment.