pyhw 0.14.1__tar.gz → 0.14.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pyhw-0.14.1/src/pyhw.egg-info → pyhw-0.14.3}/PKG-INFO +1 -1
- {pyhw-0.14.1 → pyhw-0.14.3}/pyproject.toml +1 -1
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/__init__.py +1 -1
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/__main__.py +11 -1
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/gpu/macos.py +34 -14
- pyhw-0.14.3/src/pyhw/backend/nic/macos.py +192 -0
- pyhw-0.14.3/src/pyhw/library/lib/iokitGPULib.dylib +0 -0
- pyhw-0.14.3/src/pyhw/library/lib/iokitNICLib.dylib +0 -0
- pyhw-0.14.3/src/pyhw/library/test/iokitGPULibTest.py +17 -0
- pyhw-0.14.3/src/pyhw/library/test/iokitNICLibTest.py +76 -0
- {pyhw-0.14.1 → pyhw-0.14.3/src/pyhw.egg-info}/PKG-INFO +1 -1
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw.egg-info/SOURCES.txt +3 -0
- pyhw-0.14.1/src/pyhw/backend/nic/macos.py +0 -25
- pyhw-0.14.1/src/pyhw/library/lib/iokitGPULib.dylib +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/LICENSE +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/README.md +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/setup.cfg +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/__init__.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/backendBase.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/cpu/__init__.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/cpu/bsd.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/cpu/cpuBase.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/cpu/cpuInfo.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/cpu/linux.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/cpu/macos.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/cpu/windows.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/gpu/__init__.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/gpu/bsd.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/gpu/gpuBase.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/gpu/gpuInfo.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/gpu/linux.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/gpu/windows.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/host/__init__.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/host/bsd.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/host/hostBase.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/host/hostInfo.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/host/linux.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/host/macos.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/host/windows.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/kernel/__init__.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/kernel/kernelBase.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/kernel/kernelInfo.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/kernel/unix.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/kernel/windows.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/memory/__init__.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/memory/bsd.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/memory/linux.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/memory/macos.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/memory/memoryBase.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/memory/memoryInfo.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/memory/windows.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/nic/__init__.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/nic/bsd.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/nic/linux.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/nic/nicBase.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/nic/nicInfo.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/nic/windows.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/npu/__init__.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/npu/bsd.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/npu/linux.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/npu/macos.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/npu/npuBase.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/npu/npuInfo.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/npu/windows.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/os/__init__.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/os/bsd.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/os/linux.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/os/macos.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/os/osBase.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/os/osInfo.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/os/windows.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/shell/__init__.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/shell/shellBase.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/shell/shellInfo.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/shell/unix.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/shell/windows.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/title/__init__.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/title/titleBase.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/title/titleInfo.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/title/unix.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/title/windows.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/uptime/__init__.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/uptime/bsd.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/uptime/linux.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/uptime/macos.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/uptime/uptimeBase.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/uptime/uptimeInfo.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/backend/uptime/windows.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/frontend/__init__.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/frontend/color/__init__.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/frontend/color/colorConfig.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/frontend/color/colorSet.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/frontend/color/colorUtil.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/frontend/frontendBase.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/frontend/logo/__init__.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/frontend/logo/ascii/alpine.pyhw +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/frontend/logo/ascii/arch.pyhw +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/frontend/logo/ascii/armbian.pyhw +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/frontend/logo/ascii/centos.pyhw +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/frontend/logo/ascii/debian.pyhw +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/frontend/logo/ascii/fedora.pyhw +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/frontend/logo/ascii/fedora_small.pyhw +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/frontend/logo/ascii/freebsd.pyhw +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/frontend/logo/ascii/kali.pyhw +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/frontend/logo/ascii/linux.pyhw +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/frontend/logo/ascii/linuxmint.pyhw +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/frontend/logo/ascii/macOS.pyhw +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/frontend/logo/ascii/opensuse-leap.pyhw +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/frontend/logo/ascii/opensuse-tumbleweed.pyhw +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/frontend/logo/ascii/raspbian.pyhw +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/frontend/logo/ascii/rhel.pyhw +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/frontend/logo/ascii/ubuntu.pyhw +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/frontend/logo/ascii/ubuntu_small.pyhw +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/frontend/logo/ascii/windows_10.pyhw +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/frontend/logo/ascii/windows_11.pyhw +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/frontend/logo/ascii/windows_2025.pyhw +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/frontend/logo/ascii/windows_old.pyhw +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/frontend/logo/logoBase.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/library/lib/iokitCPULib.dylib +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/library/lib/iokitHostLib.dylib +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/library/lib/nvmlGPULib_amd64.so +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/library/lib/nvmlGPULib_arm64.so +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/library/test/iokitCPULibTest.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/library/test/iokitHostLibTest.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/library/test/nvmlGPULibTest.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/pyhwException/__init__.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/pyhwException/pyhwException.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/pyhwUtil/__init__.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/pyhwUtil/cliUtil.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/pyhwUtil/pciUtil.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/pyhwUtil/pyhwUtil.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw/pyhwUtil/sysctlUtil.py +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw.egg-info/dependency_links.txt +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw.egg-info/entry_points.txt +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw.egg-info/requires.txt +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/src/pyhw.egg-info/top_level.txt +0 -0
- {pyhw-0.14.1 → pyhw-0.14.3}/test/test_cliUtil.py +0 -0
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
4
4
|
|
5
5
|
[project]
|
6
6
|
name = "pyhw"
|
7
|
-
version = "0.14.
|
7
|
+
version = "0.14.3"
|
8
8
|
description = "PyHw, a neofetch-like command line tool for fetching system information but written mostly in python."
|
9
9
|
keywords = ["neofetch", "system information", "command line tool", "python", "hardware information", "fastfetch", "fetching"]
|
10
10
|
authors = [
|
@@ -1,2 +1,2 @@
|
|
1
|
-
__version__ = '0.14.
|
1
|
+
__version__ = '0.14.3'
|
2
2
|
__author__ = 'xiaoran007'
|
@@ -154,13 +154,21 @@ def main():
|
|
154
154
|
multiprocessing.Process(target=detect_os, args=(debug_info, current_os, result_dict)),
|
155
155
|
multiprocessing.Process(target=detect_cpu, args=(debug_info, current_os, result_dict)),
|
156
156
|
multiprocessing.Process(target=detect_memory, args=(debug_info, current_os, result_dict)),
|
157
|
-
multiprocessing.Process(target=detect_pci_related, args=(debug_info, current_os, result_dict)),
|
158
157
|
]
|
159
158
|
|
159
|
+
if current_os == "macos":
|
160
|
+
processes.append(multiprocessing.Process(target=detect_gpu, args=(debug_info, current_os, result_dict)))
|
161
|
+
processes.append(multiprocessing.Process(target=detect_nic, args=(debug_info, current_os, result_dict)))
|
162
|
+
processes.append(multiprocessing.Process(target=detect_npu, args=(debug_info, current_os, result_dict)))
|
163
|
+
else:
|
164
|
+
multiprocessing.Process(target=detect_pci_related, args=(debug_info, current_os, result_dict)),
|
165
|
+
|
160
166
|
start_time = time.time()
|
161
167
|
for process in processes:
|
162
168
|
process.start()
|
163
169
|
|
170
|
+
detection_time = time.time() - start_time
|
171
|
+
|
164
172
|
for process in processes[1:]:
|
165
173
|
process.join()
|
166
174
|
|
@@ -179,6 +187,8 @@ def main():
|
|
179
187
|
for func_name, elapsed in debug_dict.items():
|
180
188
|
detection_name = func_name.replace("detect_", "")
|
181
189
|
print(f"{detection_name:<10}: {elapsed:.4f} s")
|
190
|
+
print("-" * 50)
|
191
|
+
print(f"Total create time: {detection_time:.4f} s")
|
182
192
|
print("-"*50)
|
183
193
|
print(f"Total execution time: {total_time:.4f} s")
|
184
194
|
print("="*50)
|
@@ -1,5 +1,6 @@
|
|
1
1
|
from .gpuInfo import GPUInfo
|
2
2
|
from ...pyhwUtil import getArch
|
3
|
+
from ..cpu import CPUDetect
|
3
4
|
import json
|
4
5
|
import subprocess
|
5
6
|
import ctypes
|
@@ -19,22 +20,25 @@ class GPUDetectMacOS:
|
|
19
20
|
return self.__gpuInfo
|
20
21
|
|
21
22
|
def __getGPUAppleSilicon(self):
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
23
|
+
if self.__getGPUIOKitAppleSilicon():
|
24
|
+
pass
|
25
|
+
else:
|
26
|
+
gpus = list()
|
27
|
+
try:
|
28
|
+
gpu_info_dict = json.loads(subprocess.check_output(["system_profiler", "SPDisplaysDataType", "-json"]))
|
29
|
+
if 'SPDisplaysDataType' in gpu_info_dict:
|
30
|
+
gpus = gpu_info_dict['SPDisplaysDataType']
|
31
|
+
self.__gpuInfo.number = len(gpus)
|
32
|
+
else:
|
33
|
+
pass
|
34
|
+
except Exception:
|
35
|
+
return
|
32
36
|
|
33
|
-
|
34
|
-
|
37
|
+
for gpu in gpus:
|
38
|
+
self.__gpuInfo.gpus.append(f'{gpu.get("sppci_model")} ({gpu.get("sppci_cores")} Cores) [SOC Integrated]')
|
35
39
|
|
36
40
|
def __getGPUIntel(self):
|
37
|
-
if self.
|
41
|
+
if self.__getGPUIOKitIntel():
|
38
42
|
pass
|
39
43
|
else: # fallback to the default implementation
|
40
44
|
gpus = list()
|
@@ -56,7 +60,7 @@ class GPUDetectMacOS:
|
|
56
60
|
elif self.__handleVendor(gpu.get("spdisplays_vendor")) == "Nvidia": # Since current macOS does not support NVIDIA GPUs, this condition is not applicable
|
57
61
|
pass
|
58
62
|
|
59
|
-
def
|
63
|
+
def __getGPUIOKitIntel(self):
|
60
64
|
try:
|
61
65
|
package_root = Path(__file__).resolve().parent.parent.parent
|
62
66
|
lib = ctypes.CDLL(f"{package_root}/library/lib/iokitGPULib.dylib")
|
@@ -82,6 +86,22 @@ class GPUDetectMacOS:
|
|
82
86
|
# print(f"An error occurred while getting GPU info using IOKit: {e}")
|
83
87
|
return False
|
84
88
|
|
89
|
+
def __getGPUIOKitAppleSilicon(self):
|
90
|
+
try:
|
91
|
+
package_root = Path(__file__).resolve().parent.parent.parent
|
92
|
+
lib = ctypes.CDLL(f"{package_root}/library/lib/iokitGPULib.dylib")
|
93
|
+
lib.getAppleSiliconGPUInfo.restype = ctypes.c_char_p
|
94
|
+
gpu_cores = lib.getAppleSiliconGPUInfo().decode('utf-8')
|
95
|
+
|
96
|
+
if gpu_cores == "0":
|
97
|
+
return False
|
98
|
+
self.__gpuInfo.number = 1
|
99
|
+
self.__gpuInfo.gpus.append(f'{CPUDetect(os="macos").getCPUInfo().model} ({gpu_cores} Cores) [SOC Integrated]')
|
100
|
+
return True
|
101
|
+
except Exception as e:
|
102
|
+
# print(f"An error occurred while getting GPU info using IOKit: {e}")
|
103
|
+
return False
|
104
|
+
|
85
105
|
@staticmethod
|
86
106
|
def __handleVendor(vendor):
|
87
107
|
if vendor == "sppci_vendor_Apple":
|
@@ -0,0 +1,192 @@
|
|
1
|
+
from .nicInfo import NICInfo
|
2
|
+
import subprocess
|
3
|
+
import ctypes
|
4
|
+
from ctypes import c_char_p, c_bool, c_int32, c_char, byref, create_string_buffer
|
5
|
+
from pathlib import Path
|
6
|
+
|
7
|
+
|
8
|
+
class NICDetectMacOS:
|
9
|
+
def __init__(self):
|
10
|
+
self.__nicInfo = NICInfo()
|
11
|
+
|
12
|
+
def getNICInfo(self):
|
13
|
+
self.__getNICInfo()
|
14
|
+
return self.__nicInfo
|
15
|
+
|
16
|
+
def __getNICInfo(self):
|
17
|
+
# Try to get NIC info using IOKit first
|
18
|
+
if not self.__getNICInfoIOKit():
|
19
|
+
try:
|
20
|
+
# Get default interface
|
21
|
+
cmd_get_interface = "route get default | grep interface"
|
22
|
+
interface_output = subprocess.run(["bash", "-c", cmd_get_interface],
|
23
|
+
capture_output=True, text=True).stdout.strip()
|
24
|
+
interface = interface_output.split(":")[1].strip()
|
25
|
+
|
26
|
+
# Get IP address
|
27
|
+
if_ip = subprocess.run(["bash", "-c", f"ipconfig getifaddr {interface}"],
|
28
|
+
capture_output=True, text=True).stdout.strip()
|
29
|
+
|
30
|
+
# Get interface type and link speed
|
31
|
+
link_info = self.__getLinkInfo(interface)
|
32
|
+
|
33
|
+
# Add all information to nicInfo
|
34
|
+
self.__nicInfo.nics.append(f"{interface} @ {if_ip} - {link_info}")
|
35
|
+
self.__nicInfo.number += 1
|
36
|
+
except Exception as e:
|
37
|
+
self.__handleError()
|
38
|
+
else:
|
39
|
+
pass
|
40
|
+
|
41
|
+
def __getNICInfoIOKit(self):
|
42
|
+
try:
|
43
|
+
package_root = Path(__file__).resolve().parent.parent.parent
|
44
|
+
lib = ctypes.CDLL(f"{package_root}/library/lib/iokitNICLib.dylib")
|
45
|
+
|
46
|
+
lib.getDefaultInterface.argtypes = [c_char_p]
|
47
|
+
lib.getDefaultInterface.restype = c_bool
|
48
|
+
|
49
|
+
lib.getNetworkInfo.argtypes = [c_char_p, ctypes.POINTER(c_bool),
|
50
|
+
c_char_p, ctypes.POINTER(c_int32),
|
51
|
+
c_char_p, c_char_p, c_char_p, c_char_p]
|
52
|
+
lib.getNetworkInfo.restype = c_bool
|
53
|
+
interface = create_string_buffer(32)
|
54
|
+
if lib.getDefaultInterface(interface):
|
55
|
+
interface_str = interface.value.decode('utf-8')
|
56
|
+
|
57
|
+
is_wifi = c_bool(False)
|
58
|
+
ip_address = create_string_buffer(32)
|
59
|
+
speed = c_int32(0)
|
60
|
+
band = create_string_buffer(16)
|
61
|
+
channel = create_string_buffer(32)
|
62
|
+
conn_type = create_string_buffer(32)
|
63
|
+
wifi_standard = create_string_buffer(16)
|
64
|
+
|
65
|
+
if lib.getNetworkInfo(interface_str.encode('utf-8'),
|
66
|
+
byref(is_wifi),
|
67
|
+
ip_address,
|
68
|
+
byref(speed),
|
69
|
+
band,
|
70
|
+
channel,
|
71
|
+
conn_type,
|
72
|
+
wifi_standard):
|
73
|
+
|
74
|
+
if is_wifi.value:
|
75
|
+
conn_info = f"{conn_type.value.decode('utf-8')} 802.11{wifi_standard.value.decode('utf-8')} ({band.value.decode('utf-8')} {speed.value} Mbps)"
|
76
|
+
else:
|
77
|
+
conn_info = conn_type.value.decode('utf-8')
|
78
|
+
|
79
|
+
formatted_output = f"{interface_str} @ {ip_address.value.decode('utf-8')} - {conn_info}"
|
80
|
+
|
81
|
+
self.__nicInfo.nics.append(formatted_output)
|
82
|
+
self.__nicInfo.number += 1
|
83
|
+
|
84
|
+
return True
|
85
|
+
|
86
|
+
else:
|
87
|
+
return False
|
88
|
+
else:
|
89
|
+
return False
|
90
|
+
|
91
|
+
except Exception as e:
|
92
|
+
# print(f"An error occurred while getting NIC info using IOKit: {e}")
|
93
|
+
return False
|
94
|
+
|
95
|
+
|
96
|
+
def __getLinkInfo(self, interface):
|
97
|
+
try:
|
98
|
+
# Check if interface is wireless
|
99
|
+
is_wifi_cmd = f"networksetup -getairportpower {interface} 2>/dev/null"
|
100
|
+
is_wifi_result = subprocess.run(["bash", "-c", is_wifi_cmd],
|
101
|
+
capture_output=True, text=True).returncode
|
102
|
+
|
103
|
+
if is_wifi_result == 0: # This is a Wi-Fi interface
|
104
|
+
speed, channel, band = self.__getWifiInfo(interface)
|
105
|
+
return f"Wi-Fi {band} ({speed} Mbps)"
|
106
|
+
else:
|
107
|
+
# For wired connections, get link speed using networksetup
|
108
|
+
media_cmd = f"networksetup -getmedia {interface} | grep 'Active'"
|
109
|
+
media_info = subprocess.run(["bash", "-c", media_cmd],
|
110
|
+
capture_output=True, text=True).stdout.strip()
|
111
|
+
|
112
|
+
if media_info:
|
113
|
+
parts = media_info.split(':', 1)
|
114
|
+
if len(parts) > 1:
|
115
|
+
# Extract "2500Base-T <full-duplex>" part
|
116
|
+
media_details = parts[1].strip()
|
117
|
+
|
118
|
+
# Parse the speed part (e.g., "2500Base-T")
|
119
|
+
speed_part = media_details.split()[0] if media_details else ""
|
120
|
+
|
121
|
+
if "2500Base-T" in speed_part:
|
122
|
+
return "Wired (2.5 Gbps)"
|
123
|
+
elif "1000Base-T" in speed_part:
|
124
|
+
return "Wired (1 Gbps)"
|
125
|
+
elif "100Base-T" in speed_part:
|
126
|
+
return "Wired (100 Mbps)"
|
127
|
+
elif "10000Base-T" in speed_part:
|
128
|
+
return "Wired (10 Gbps)"
|
129
|
+
elif "Base-T" in speed_part or "base-T" in speed_part:
|
130
|
+
# Extract the numeric part from formats like "5000Base-T"
|
131
|
+
import re
|
132
|
+
speed_match = re.search(r'(\d+)(?:Base-T|base-T)', speed_part)
|
133
|
+
if speed_match:
|
134
|
+
speed_value = int(speed_match.group(1))
|
135
|
+
if speed_value >= 1000:
|
136
|
+
return f"Wired ({speed_value / 1000:.1f} Gbps)"
|
137
|
+
else:
|
138
|
+
return f"Wired ({speed_value} Mbps)"
|
139
|
+
return f"Wired ({speed_part})"
|
140
|
+
except:
|
141
|
+
return "Unknown connection type"
|
142
|
+
|
143
|
+
def __getWifiInfo(self, interface):
|
144
|
+
# 使用 system_profiler 获取 WiFi 信息
|
145
|
+
profiler_cmd = f"system_profiler SPAirPortDataType -json"
|
146
|
+
try:
|
147
|
+
wifi_data = subprocess.run(["bash", "-c", profiler_cmd],
|
148
|
+
capture_output=True, text=True, timeout=5).stdout
|
149
|
+
|
150
|
+
import json
|
151
|
+
data = json.loads(wifi_data)
|
152
|
+
|
153
|
+
# 根据实际 JSON 结构提取信息
|
154
|
+
if 'SPAirPortDataType' in data and isinstance(data['SPAirPortDataType'], list):
|
155
|
+
airport_data = data['SPAirPortDataType'][0]
|
156
|
+
|
157
|
+
# 获取接口列表
|
158
|
+
if 'spairport_airport_interfaces' in airport_data:
|
159
|
+
interfaces = airport_data['spairport_airport_interfaces']
|
160
|
+
|
161
|
+
# 查找匹配的接口
|
162
|
+
for iface in interfaces:
|
163
|
+
if interface == iface.get('_name', ''):
|
164
|
+
# 获取当前网络信息
|
165
|
+
current_network = iface.get('spairport_current_network_information', {})
|
166
|
+
|
167
|
+
# 从当前连接中提取速率
|
168
|
+
speed = current_network.get('spairport_network_rate', 'Unknown')
|
169
|
+
|
170
|
+
# 获取信道信息
|
171
|
+
channel_info = current_network.get('spairport_network_channel', 'Unknown')
|
172
|
+
|
173
|
+
# 确定频段信息
|
174
|
+
band = "Unknown"
|
175
|
+
if isinstance(channel_info, str) and "GHz" in channel_info:
|
176
|
+
if "2GHz" in channel_info:
|
177
|
+
band = "2.4GHz"
|
178
|
+
elif "5GHz" in channel_info:
|
179
|
+
band = "5GHz"
|
180
|
+
elif "6GHz" in channel_info:
|
181
|
+
band = "6GHz"
|
182
|
+
|
183
|
+
return speed, channel_info, band
|
184
|
+
|
185
|
+
return "Unknown", "Unknown", "Unknown"
|
186
|
+
except Exception as e:
|
187
|
+
# 可以考虑添加日志记录 print(f"WiFi info error: {str(e)}")
|
188
|
+
return "Unknown", "Unknown", "Unknown"
|
189
|
+
|
190
|
+
def __handleError(self):
|
191
|
+
self.__nicInfo.nics.append("en0 - Unknown connection")
|
192
|
+
self.__nicInfo.number = 1
|
Binary file
|
Binary file
|
@@ -0,0 +1,17 @@
|
|
1
|
+
import ctypes
|
2
|
+
|
3
|
+
|
4
|
+
def main():
|
5
|
+
lib = ctypes.CDLL(f"../lib/iokitGPULib.dylib")
|
6
|
+
lib.getGPUInfo.restype = ctypes.c_char_p
|
7
|
+
lib.getAppleSiliconGPUInfo.restype = ctypes.c_char_p
|
8
|
+
gpu_info = lib.getAppleSiliconGPUInfo()
|
9
|
+
print(gpu_info.decode('utf-8'))
|
10
|
+
|
11
|
+
|
12
|
+
if __name__ == "__main__":
|
13
|
+
main()
|
14
|
+
|
15
|
+
|
16
|
+
|
17
|
+
|
@@ -0,0 +1,76 @@
|
|
1
|
+
import ctypes
|
2
|
+
from ctypes import c_char_p, c_bool, c_int32, c_char, byref, create_string_buffer
|
3
|
+
import os
|
4
|
+
|
5
|
+
|
6
|
+
def main():
|
7
|
+
current_dir = os.path.dirname(os.path.abspath(__file__))
|
8
|
+
lib_path = os.path.join(current_dir, "../lib/iokitNICLib.dylib")
|
9
|
+
|
10
|
+
try:
|
11
|
+
lib = ctypes.CDLL(lib_path)
|
12
|
+
|
13
|
+
lib.getDefaultInterface.argtypes = [c_char_p]
|
14
|
+
lib.getDefaultInterface.restype = c_bool
|
15
|
+
|
16
|
+
lib.getNetworkInfo.argtypes = [c_char_p, ctypes.POINTER(c_bool),
|
17
|
+
c_char_p, ctypes.POINTER(c_int32),
|
18
|
+
c_char_p, c_char_p, c_char_p, c_char_p]
|
19
|
+
lib.getNetworkInfo.restype = c_bool
|
20
|
+
|
21
|
+
interface = create_string_buffer(32)
|
22
|
+
if lib.getDefaultInterface(interface):
|
23
|
+
interface_str = interface.value.decode('utf-8')
|
24
|
+
|
25
|
+
# interface_str = "en1"
|
26
|
+
print(f"默认网络接口: {interface_str}")
|
27
|
+
|
28
|
+
is_wifi = c_bool(False)
|
29
|
+
ip_address = create_string_buffer(32)
|
30
|
+
speed = c_int32(0)
|
31
|
+
band = create_string_buffer(16)
|
32
|
+
channel = create_string_buffer(32)
|
33
|
+
conn_type = create_string_buffer(32)
|
34
|
+
wifi_standard = create_string_buffer(16)
|
35
|
+
|
36
|
+
if lib.getNetworkInfo(interface_str.encode('utf-8'),
|
37
|
+
byref(is_wifi),
|
38
|
+
ip_address,
|
39
|
+
byref(speed),
|
40
|
+
band,
|
41
|
+
channel,
|
42
|
+
conn_type,
|
43
|
+
wifi_standard):
|
44
|
+
|
45
|
+
print("=== 网络信息 ===")
|
46
|
+
print(f"接口: {interface_str}")
|
47
|
+
print(f"IP地址: {ip_address.value.decode('utf-8')}")
|
48
|
+
print(f"连接类型: {conn_type.value.decode('utf-8')}")
|
49
|
+
print(f"速度: {speed.value} Mbps")
|
50
|
+
|
51
|
+
if is_wifi.value:
|
52
|
+
print(f"Wi-Fi频段: {band.value.decode('utf-8')}")
|
53
|
+
print(f"信道: {channel.value.decode('utf-8')}")
|
54
|
+
print(f"Wi-Fi标准: {wifi_standard.value.decode('utf-8')}")
|
55
|
+
|
56
|
+
if is_wifi.value:
|
57
|
+
wifi_info = f"{wifi_standard.value.decode('utf-8')} {band.value.decode('utf-8')}"
|
58
|
+
conn_info = f"{conn_type.value.decode('utf-8')} ({wifi_info}, {speed.value} Mbps)"
|
59
|
+
else:
|
60
|
+
conn_info = conn_type.value.decode('utf-8')
|
61
|
+
|
62
|
+
formatted_output = f"{interface_str} @ {ip_address.value.decode('utf-8')} - {conn_info}"
|
63
|
+
print("\n格式化输出:")
|
64
|
+
print(formatted_output)
|
65
|
+
else:
|
66
|
+
print(f"无法获取接口 {interface_str} 的网络信息")
|
67
|
+
else:
|
68
|
+
print("无法获取默认网络接口")
|
69
|
+
|
70
|
+
except Exception as e:
|
71
|
+
print(f"错误: {e}")
|
72
|
+
|
73
|
+
|
74
|
+
if __name__ == "__main__":
|
75
|
+
main()
|
76
|
+
|
@@ -115,10 +115,13 @@ src/pyhw/frontend/logo/ascii/windows_old.pyhw
|
|
115
115
|
src/pyhw/library/lib/iokitCPULib.dylib
|
116
116
|
src/pyhw/library/lib/iokitGPULib.dylib
|
117
117
|
src/pyhw/library/lib/iokitHostLib.dylib
|
118
|
+
src/pyhw/library/lib/iokitNICLib.dylib
|
118
119
|
src/pyhw/library/lib/nvmlGPULib_amd64.so
|
119
120
|
src/pyhw/library/lib/nvmlGPULib_arm64.so
|
120
121
|
src/pyhw/library/test/iokitCPULibTest.py
|
122
|
+
src/pyhw/library/test/iokitGPULibTest.py
|
121
123
|
src/pyhw/library/test/iokitHostLibTest.py
|
124
|
+
src/pyhw/library/test/iokitNICLibTest.py
|
122
125
|
src/pyhw/library/test/nvmlGPULibTest.py
|
123
126
|
src/pyhw/pyhwException/__init__.py
|
124
127
|
src/pyhw/pyhwException/pyhwException.py
|
@@ -1,25 +0,0 @@
|
|
1
|
-
from .nicInfo import NICInfo
|
2
|
-
import subprocess
|
3
|
-
|
4
|
-
|
5
|
-
class NICDetectMacOS:
|
6
|
-
def __init__(self):
|
7
|
-
self.__nicInfo = NICInfo()
|
8
|
-
|
9
|
-
def getNICInfo(self):
|
10
|
-
self.__getNICInfo()
|
11
|
-
return self.__nicInfo
|
12
|
-
|
13
|
-
def __getNICInfo(self):
|
14
|
-
# Placeholder for a more advanced method.
|
15
|
-
try:
|
16
|
-
interface = subprocess.run(["bash", "-c", "route get default | grep interface"], capture_output=True, text=True).stdout.strip().split(":")[1]
|
17
|
-
if_ip = subprocess.run(["bash", "-c", f"ipconfig getifaddr {interface}"], capture_output=True, text=True).stdout.strip()
|
18
|
-
self.__nicInfo.nics.append(f"{interface} @ {if_ip}")
|
19
|
-
self.__nicInfo.number += 1
|
20
|
-
except:
|
21
|
-
self.__handleError()
|
22
|
-
|
23
|
-
def __handleError(self):
|
24
|
-
self.__nicInfo.nics.append("en0")
|
25
|
-
self.__nicInfo.number = 1
|
Binary file
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|