pyhw 0.2.0b0__py3-none-any.whl → 0.7.4__py3-none-any.whl
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/__init__.py +1 -1
- pyhw/__main__.py +10 -3
- pyhw/backend/backendBase.py +2 -0
- pyhw/backend/cpu/bsd.py +12 -0
- pyhw/backend/cpu/cpuBase.py +3 -0
- pyhw/backend/cpu/linux.py +26 -0
- pyhw/backend/cpu/macos.py +3 -1
- pyhw/backend/gpu/bsd.py +7 -0
- pyhw/backend/gpu/gpuBase.py +3 -0
- pyhw/backend/gpu/linux.py +20 -11
- pyhw/backend/gpu/macos.py +54 -17
- pyhw/backend/host/bsd.py +13 -0
- pyhw/backend/host/hostBase.py +3 -0
- pyhw/backend/host/linux.py +48 -21
- pyhw/backend/host/macos.py +11 -1
- pyhw/backend/kernel/kernelBase.py +1 -3
- pyhw/backend/memory/bsd.py +11 -0
- pyhw/backend/memory/linux.py +8 -8
- pyhw/backend/memory/memoryBase.py +3 -0
- pyhw/backend/nic/__init__.py +4 -0
- pyhw/backend/nic/bsd.py +7 -0
- pyhw/backend/nic/linux.py +58 -0
- pyhw/backend/nic/macos.py +27 -0
- pyhw/backend/nic/nicBase.py +25 -0
- pyhw/backend/nic/nicInfo.py +8 -0
- pyhw/backend/npu/__init__.py +5 -0
- pyhw/backend/npu/bsd.py +6 -0
- pyhw/backend/npu/linux.py +38 -0
- pyhw/backend/npu/macos.py +65 -0
- pyhw/backend/npu/npuBase.py +20 -0
- pyhw/backend/npu/npuInfo.py +10 -0
- pyhw/backend/os/bsd.py +7 -0
- pyhw/backend/os/linux.py +20 -15
- pyhw/backend/os/macos.py +21 -3
- pyhw/backend/os/osBase.py +3 -0
- pyhw/backend/shell/shellBase.py +1 -1
- pyhw/backend/shell/unix.py +20 -2
- pyhw/backend/title/titleBase.py +1 -1
- pyhw/backend/uptime/bsd.py +7 -0
- pyhw/backend/uptime/macos.py +12 -12
- pyhw/backend/uptime/uptimeBase.py +3 -0
- pyhw/frontend/color/colorConfig.py +70 -1
- pyhw/frontend/frontendBase.py +41 -2
- pyhw/frontend/logo/ascii/alpine.pyhw +6 -0
- pyhw/frontend/logo/ascii/arch.pyhw +19 -0
- pyhw/frontend/logo/ascii/armbian.pyhw +14 -0
- pyhw/frontend/logo/ascii/centos.pyhw +19 -0
- pyhw/frontend/logo/ascii/freebsd.pyhw +15 -0
- pyhw/frontend/logo/ascii/raspbian.pyhw +10 -0
- pyhw/library/lib/iokitGPULib.dylib +0 -0
- pyhw/pyhwUtil/__init__.py +2 -2
- pyhw/pyhwUtil/pyhwUtil.py +137 -4
- pyhw-0.7.4.dist-info/METADATA +135 -0
- pyhw-0.7.4.dist-info/RECORD +99 -0
- {pyhw-0.2.0b0.dist-info → pyhw-0.7.4.dist-info}/WHEEL +1 -1
- pyhw/macos.py +0 -146
- pyhw-0.2.0b0.dist-info/METADATA +0 -50
- pyhw-0.2.0b0.dist-info/RECORD +0 -75
- {pyhw-0.2.0b0.dist-info → pyhw-0.7.4.dist-info}/LICENSE +0 -0
- {pyhw-0.2.0b0.dist-info → pyhw-0.7.4.dist-info}/entry_points.txt +0 -0
- {pyhw-0.2.0b0.dist-info → pyhw-0.7.4.dist-info}/top_level.txt +0 -0
pyhw/__init__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__ = '0.
|
1
|
+
__version__ = '0.7.4'
|
pyhw/__main__.py
CHANGED
@@ -9,15 +9,16 @@ from .backend.os import OSDetect
|
|
9
9
|
from .backend.cpu import CPUDetect
|
10
10
|
from .backend.gpu import GPUDetect
|
11
11
|
from .backend.memory import MemoryDetect
|
12
|
+
from .backend.nic import NICDetect
|
13
|
+
from .backend.npu import NPUDetect
|
12
14
|
from .pyhwUtil import createDataString
|
13
15
|
from .pyhwUtil import getOS, selectOSLogo
|
14
16
|
|
15
17
|
|
16
18
|
def main():
|
17
19
|
current_os = getOS()
|
18
|
-
|
19
|
-
|
20
|
-
print(f"Only Linux and macOS is supported for now. Current os: {current_os}")
|
20
|
+
if current_os not in ["linux", "macos", "freebsd"]:
|
21
|
+
print(f"Only Linux, macOS, and FreeBSD is supported for now. Current os: {current_os}")
|
21
22
|
return
|
22
23
|
data = Data()
|
23
24
|
data.title = TitleDetect(os=current_os).getTitle().title
|
@@ -31,6 +32,12 @@ def main():
|
|
31
32
|
if gpu_info.number > 0:
|
32
33
|
data.GPU = gpu_info.gpus
|
33
34
|
data.Memory = MemoryDetect(os=current_os).getMemoryInfo().memory
|
35
|
+
nic_info = NICDetect(os=current_os).getNICInfo()
|
36
|
+
if nic_info.number > 0:
|
37
|
+
data.NIC = nic_info.nics
|
38
|
+
npu_info = NPUDetect(os=current_os).getNPUInfo()
|
39
|
+
if npu_info.number > 0:
|
40
|
+
data.NPU = npu_info.npus
|
34
41
|
|
35
42
|
Printer(logo_os=selectOSLogo(OSDetect(os=current_os).getOSInfo().id), data=createDataString(data)).cPrint()
|
36
43
|
|
pyhw/backend/backendBase.py
CHANGED
pyhw/backend/cpu/bsd.py
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
from .cpuInfo import CPUInfo
|
2
|
+
from ...pyhwUtil import sysctlGetString, sysctlGetInt, getArch
|
3
|
+
|
4
|
+
|
5
|
+
class CPUDetectBSD:
|
6
|
+
def __init__(self):
|
7
|
+
self.__cpuInfo = CPUInfo()
|
8
|
+
|
9
|
+
def getCPUInfo(self):
|
10
|
+
self.__cpuInfo.cpu = sysctlGetString("hw.model")
|
11
|
+
return self.__cpuInfo
|
12
|
+
|
pyhw/backend/cpu/cpuBase.py
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
from .linux import CPUDetectLinux
|
2
2
|
from .macos import CPUDetectMacOS
|
3
|
+
from .bsd import CPUDetectBSD
|
3
4
|
from ...pyhwException import OSUnsupportedException
|
4
5
|
|
5
6
|
|
@@ -12,5 +13,7 @@ class CPUDetect:
|
|
12
13
|
return CPUDetectLinux().getCPUInfo()
|
13
14
|
elif self.OS == "macos":
|
14
15
|
return CPUDetectMacOS().getCPUInfo()
|
16
|
+
elif self.OS == "freebsd":
|
17
|
+
return CPUDetectBSD().getCPUInfo()
|
15
18
|
else:
|
16
19
|
raise OSUnsupportedException("Unsupported operating system")
|
pyhw/backend/cpu/linux.py
CHANGED
@@ -10,6 +10,9 @@ class CPUDetectLinux:
|
|
10
10
|
def getCPUInfo(self):
|
11
11
|
self.__getCPUInfo()
|
12
12
|
self.__modelClean()
|
13
|
+
self.__handleSBC()
|
14
|
+
if self.__cpuInfo.model == "":
|
15
|
+
self.__cpuInfo.model = "Unknown"
|
13
16
|
if self.__cpuInfo.model != "":
|
14
17
|
self.__cpuInfo.cpu = self.__cpuInfo.model
|
15
18
|
if self.__cpuInfo.cores != "":
|
@@ -51,3 +54,26 @@ class CPUDetectLinux:
|
|
51
54
|
def __modelClean(self):
|
52
55
|
self.__cpuInfo.model = self.__cpuInfo.model.replace("(R)", "")
|
53
56
|
self.__cpuInfo.model = self.__cpuInfo.model.replace("(TM)", "")
|
57
|
+
|
58
|
+
def __handleSBC(self):
|
59
|
+
# some values should be double-checked
|
60
|
+
# Info source: https://github.com/raspberrypi/firmware/tree/master/boot
|
61
|
+
if os.path.exists("/sys/firmware/devicetree/base/compatible"):
|
62
|
+
try:
|
63
|
+
with open("/sys/firmware/devicetree/base/compatible", "r") as f:
|
64
|
+
compatible = f.read().strip()
|
65
|
+
except FileNotFoundError:
|
66
|
+
compatible = ""
|
67
|
+
if "raspberrypi" in compatible:
|
68
|
+
model = compatible.split(",")[-1]
|
69
|
+
if model.startswith("bcm"):
|
70
|
+
self.__cpuInfo.model = model.upper()
|
71
|
+
elif "orangepi" in compatible:
|
72
|
+
if "allwinner" in compatible:
|
73
|
+
model = compatible.split(",")[-1]
|
74
|
+
if model.startswith("sun"):
|
75
|
+
self.__cpuInfo.model = f"Allwinner {model.split('-')[-1].upper()} ({model})"
|
76
|
+
else:
|
77
|
+
pass
|
78
|
+
|
79
|
+
|
pyhw/backend/cpu/macos.py
CHANGED
@@ -64,6 +64,8 @@ class CPUDetectMacOS:
|
|
64
64
|
"Apple M3": "4.05 GHz",
|
65
65
|
"Apple M3 Pro": "4.05 GHz",
|
66
66
|
"Apple M3 Max": "4.05 GHz",
|
67
|
-
"Apple M4": "4.40 GHz"
|
67
|
+
"Apple M4": "4.40 GHz",
|
68
|
+
"Apple M4 Pro": "4.40 GHz",
|
69
|
+
"Apple M4 Max": "4.40 GHz"
|
68
70
|
}
|
69
71
|
self.__cpuInfo.frequency = freq.get(self.__cpuInfo.model, "Unknown")
|
pyhw/backend/gpu/bsd.py
ADDED
pyhw/backend/gpu/gpuBase.py
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
from .linux import GPUDetectLinux
|
2
2
|
from .macos import GPUDetectMacOS
|
3
|
+
from .bsd import GPUDetectBSD
|
3
4
|
|
4
5
|
|
5
6
|
class GPUDetect:
|
@@ -11,5 +12,7 @@ class GPUDetect:
|
|
11
12
|
return GPUDetectLinux().getGPUInfo()
|
12
13
|
elif self.OS == "macos":
|
13
14
|
return GPUDetectMacOS().getGPUInfo()
|
15
|
+
elif self.OS == "freebsd":
|
16
|
+
return GPUDetectBSD().getGPUInfo()
|
14
17
|
else:
|
15
18
|
raise NotImplementedError("Unsupported operating system")
|
pyhw/backend/gpu/linux.py
CHANGED
@@ -2,6 +2,7 @@ import subprocess
|
|
2
2
|
from .gpuInfo import GPUInfo
|
3
3
|
from ..cpu import CPUDetect
|
4
4
|
from ...pyhwUtil import getArch
|
5
|
+
import pypci
|
5
6
|
|
6
7
|
|
7
8
|
class GPUDetectLinux:
|
@@ -10,22 +11,21 @@ class GPUDetectLinux:
|
|
10
11
|
|
11
12
|
def getGPUInfo(self):
|
12
13
|
self.__getGPUInfo()
|
14
|
+
self.__sortGPUList()
|
13
15
|
return self.__gpuInfo
|
14
16
|
|
15
17
|
def __getGPUInfo(self):
|
16
|
-
|
17
|
-
|
18
|
-
except subprocess.SubprocessError:
|
19
|
-
return
|
20
|
-
if len(pci_info) == 0: # no pcie devices found
|
18
|
+
gpu_devices = pypci.PCI().FindAllVGA()
|
19
|
+
if len(gpu_devices) == 0:
|
21
20
|
self.__handleNonePciDevices()
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
21
|
+
else:
|
22
|
+
for device in gpu_devices:
|
23
|
+
if device.subsystem_device_name != "":
|
24
|
+
device_name = f"{device.vendor_name} {device.device_name} ({device.subsystem_device_name})"
|
25
|
+
else:
|
26
|
+
device_name = f"{device.vendor_name} {device.device_name}"
|
27
|
+
self.__gpuInfo.gpus.append(self.__gpuNameClean(device_name))
|
26
28
|
self.__gpuInfo.number += 1
|
27
|
-
if self.__gpuInfo.number == 0:
|
28
|
-
self.__handleNonePciDevices() # fallback to a sbc device detection method
|
29
29
|
|
30
30
|
def __handleNonePciDevices(self):
|
31
31
|
# if detector can't find any VGA/Display/3D GPUs, assume the host is a sbc device, this function is a placeholder for a more advanced method.
|
@@ -35,3 +35,12 @@ class GPUDetectLinux:
|
|
35
35
|
else:
|
36
36
|
self.__gpuInfo.number = 1
|
37
37
|
self.__gpuInfo.gpus.append("Not found")
|
38
|
+
|
39
|
+
@staticmethod
|
40
|
+
def __gpuNameClean(gpu_name: str):
|
41
|
+
gpu_name_clean = gpu_name.replace("Corporation ", "")
|
42
|
+
return gpu_name_clean
|
43
|
+
|
44
|
+
def __sortGPUList(self):
|
45
|
+
self.__gpuInfo.gpus.sort()
|
46
|
+
|
pyhw/backend/gpu/macos.py
CHANGED
@@ -2,6 +2,8 @@ from .gpuInfo import GPUInfo
|
|
2
2
|
from ...pyhwUtil import getArch
|
3
3
|
import json
|
4
4
|
import subprocess
|
5
|
+
import ctypes
|
6
|
+
from pathlib import Path
|
5
7
|
|
6
8
|
|
7
9
|
class GPUDetectMacOS:
|
@@ -32,24 +34,49 @@ class GPUDetectMacOS:
|
|
32
34
|
self.__gpuInfo.gpus.append(f'{gpu.get("sppci_model")} ({gpu.get("sppci_cores")} cores) [SOC Integrated]')
|
33
35
|
|
34
36
|
def __getGPUIntel(self):
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
37
|
+
if self.__getGPUIOKit():
|
38
|
+
pass
|
39
|
+
else: # fallback to the default implementation
|
40
|
+
gpus = list()
|
41
|
+
try:
|
42
|
+
gpu_info_dict = json.loads(subprocess.check_output(["system_profiler", "SPDisplaysDataType", "-json"]))
|
43
|
+
if 'SPDisplaysDataType' in gpu_info_dict:
|
44
|
+
gpus = gpu_info_dict['SPDisplaysDataType']
|
45
|
+
self.__gpuInfo.number = len(gpus)
|
46
|
+
else:
|
47
|
+
pass
|
48
|
+
except Exception:
|
49
|
+
return
|
45
50
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
51
|
+
for gpu in gpus:
|
52
|
+
if self.__handleVendor(gpu.get("spdisplays_vendor")) == "Intel": # Integrated GPU
|
53
|
+
self.__gpuInfo.gpus.append(f'{gpu.get("sppci_model")} [CPU Integrated]')
|
54
|
+
elif self.__handleVendor(gpu.get("spdisplays_vendor")) == "AMD": # dGPU
|
55
|
+
self.__gpuInfo.gpus.append(f'{gpu.get("sppci_model")} {gpu.get("spdisplays_vram")} [Discrete]')
|
56
|
+
elif self.__handleVendor(gpu.get("spdisplays_vendor")) == "Nvidia": # Since current macOS does not support NVIDIA GPUs, this condition is not applicable
|
57
|
+
pass
|
58
|
+
|
59
|
+
def __getGPUIOKit(self):
|
60
|
+
try:
|
61
|
+
package_root = Path(__file__).resolve().parent.parent.parent
|
62
|
+
lib = ctypes.CDLL(f"{package_root}/library/lib/iokitGPULib.dylib")
|
63
|
+
lib.getGPUInfo.restype = ctypes.c_char_p
|
64
|
+
gpu_info = lib.getGPUInfo()
|
65
|
+
gpus = gpu_info.decode('utf-8').split("; ")
|
66
|
+
self.__gpuInfo.number = len(gpus)
|
67
|
+
for gpu in gpus:
|
68
|
+
info_list = gpu.split(", ")
|
69
|
+
model = info_list[0]
|
70
|
+
vendor_id = info_list[1]
|
71
|
+
vram = round(int(info_list[2]) / 1024, None)
|
72
|
+
if self.__handleVendorID(vendor_id) == "Intel": # Integrated GPU
|
73
|
+
self.__gpuInfo.gpus.append(f'{model} [CPU Integrated]')
|
74
|
+
elif self.__handleVendorID(vendor_id) == "AMD": # dGPU
|
75
|
+
self.__gpuInfo.gpus.append(f'{model} {vram} GB [Discrete]')
|
76
|
+
return True
|
77
|
+
except Exception as e:
|
78
|
+
# print(f"An error occurred while getting GPU info using IOKit: {e}")
|
79
|
+
return False
|
53
80
|
|
54
81
|
@staticmethod
|
55
82
|
def __handleVendor(vendor):
|
@@ -61,3 +88,13 @@ class GPUDetectMacOS:
|
|
61
88
|
return "AMD"
|
62
89
|
else:
|
63
90
|
return vendor
|
91
|
+
|
92
|
+
@staticmethod
|
93
|
+
def __handleVendorID(vendor_id):
|
94
|
+
if vendor_id == "0x8086":
|
95
|
+
return "Intel"
|
96
|
+
elif vendor_id == "0x1002":
|
97
|
+
return "AMD"
|
98
|
+
else:
|
99
|
+
return vendor_id
|
100
|
+
|
pyhw/backend/host/bsd.py
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
from .linux import HostDetectLinux
|
2
|
+
|
3
|
+
|
4
|
+
class HostDetectBSD(HostDetectLinux):
|
5
|
+
def __init__(self):
|
6
|
+
HostDetectLinux.__init__(self)
|
7
|
+
|
8
|
+
def getHostInfo(self):
|
9
|
+
self._hostInfo.name = f"General {self._arch} FreeBSD Host"
|
10
|
+
self._hostInfo.version = ""
|
11
|
+
self._hostInfo.model = self._hostInfo.name + " " + self._hostInfo.version
|
12
|
+
return self._hostInfo
|
13
|
+
|
pyhw/backend/host/hostBase.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
from .linux import HostDetectLinux
|
2
2
|
from .macos import HostDetectMacOS
|
3
3
|
from .windows import HostDetectWindows
|
4
|
+
from .bsd import HostDetectBSD
|
4
5
|
from ...pyhwException import OSUnsupportedException
|
5
6
|
|
6
7
|
|
@@ -13,6 +14,8 @@ class HostDetect:
|
|
13
14
|
return HostDetectLinux().getHostInfo()
|
14
15
|
elif self.OS == "macos":
|
15
16
|
return HostDetectMacOS().getHostInfo()
|
17
|
+
elif self.OS == "freebsd":
|
18
|
+
return HostDetectBSD().getHostInfo()
|
16
19
|
elif self.OS == "windows":
|
17
20
|
pass
|
18
21
|
else:
|
pyhw/backend/host/linux.py
CHANGED
@@ -1,35 +1,62 @@
|
|
1
1
|
"""
|
2
2
|
In dev.
|
3
3
|
"""
|
4
|
-
from ...pyhwUtil import getArch
|
4
|
+
from ...pyhwUtil import getArch, getDocker
|
5
5
|
from .hostInfo import HostInfo
|
6
|
+
import os
|
6
7
|
|
7
8
|
|
8
9
|
class HostDetectLinux:
|
9
10
|
def __init__(self):
|
10
|
-
self.
|
11
|
-
self.
|
11
|
+
self._hostInfo = HostInfo()
|
12
|
+
self._arch = getArch()
|
13
|
+
self._docker = getDocker()
|
12
14
|
|
13
15
|
def getHostInfo(self):
|
14
|
-
self.
|
15
|
-
return self.
|
16
|
+
self._getModel()
|
17
|
+
return self._hostInfo
|
16
18
|
|
17
|
-
def
|
18
|
-
if self.
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
19
|
+
def _getModel(self):
|
20
|
+
if self._docker:
|
21
|
+
self._hostInfo.name = f"General {self._arch} Docker Host"
|
22
|
+
self._hostInfo.version = ""
|
23
|
+
self._hostInfo.model = self._hostInfo.name + " " + self._hostInfo.version
|
24
|
+
else:
|
25
|
+
if self._arch in ["x86_64", "x86"]:
|
26
|
+
try:
|
27
|
+
with open("/sys/devices/virtual/dmi/id/product_name", "r") as f:
|
28
|
+
product_name = f.read().strip()
|
29
|
+
if product_name.startswith("To be filled by O.E.M."):
|
30
|
+
self._hostInfo.name = f"General {self._arch} Host"
|
31
|
+
else:
|
32
|
+
self._hostInfo.name = product_name
|
33
|
+
with open("/sys/devices/virtual/dmi/id/product_version", "r") as f:
|
34
|
+
version = f.read().strip()
|
35
|
+
if version.startswith("To be filled by O.E.M."):
|
36
|
+
self._hostInfo.version = ""
|
37
|
+
else:
|
38
|
+
self._hostInfo.version = version
|
39
|
+
self._hostInfo.model = self._hostInfo.name + " " + self._hostInfo.version
|
40
|
+
except FileNotFoundError:
|
41
|
+
pass
|
42
|
+
elif self._arch in ["aarch64", "arm32"]:
|
43
|
+
# try to find dmi folder since some arm based desktops and servers may have same structure as x86_64 machines.
|
44
|
+
if os.path.exists("/sys/devices/virtual/dmi/id"):
|
45
|
+
try:
|
46
|
+
with open("/sys/devices/virtual/dmi/id/product_name", "r") as f:
|
47
|
+
self._hostInfo.name = f.read().strip()
|
48
|
+
with open("/sys/devices/virtual/dmi/id/product_version", "r") as f:
|
49
|
+
self._hostInfo.version = f.read().strip()
|
50
|
+
self._hostInfo.model = self._hostInfo.name + " " + self._hostInfo.version
|
51
|
+
except FileNotFoundError:
|
52
|
+
pass
|
53
|
+
else:
|
54
|
+
# some single board computers may not have dmi folder, try to find model name in device tree.
|
55
|
+
try:
|
56
|
+
with open("/sys/firmware/devicetree/base/model", "r") as f:
|
57
|
+
self._hostInfo.model = f.read().strip()
|
58
|
+
except FileNotFoundError:
|
59
|
+
pass
|
33
60
|
|
34
61
|
def __getHostFamily(self):
|
35
62
|
pass
|
pyhw/backend/host/macos.py
CHANGED
@@ -172,6 +172,16 @@ class HostDetectMacOS:
|
|
172
172
|
|
173
173
|
elif hw_model.startswith("Mac"):
|
174
174
|
version = hw_model[len("Mac"):]
|
175
|
+
if self.__hwModelCheck(version, "16,3"):
|
176
|
+
return "iMac (24-inch, 2024, Four Thunderbolt / USB 4 ports)"
|
177
|
+
if self.__hwModelCheck(version, "16,2"):
|
178
|
+
return "iMac (24-inch, 2024, Two Thunderbolt / USB 4 ports)"
|
179
|
+
if self.__hwModelCheck(version, "16,1") or self.__hwModelCheck(version, "16,6") or self.__hwModelCheck(version, "16,8"):
|
180
|
+
return "MacBook Pro (14-inch, 2024, Three Thunderbolt 4 ports)"
|
181
|
+
if self.__hwModelCheck(version, "16,5") or self.__hwModelCheck(version, "16,7"):
|
182
|
+
return "MacBook Pro (16-inch, 2024, Three Thunderbolt 4 ports)"
|
183
|
+
if self.__hwModelCheck(version, "16,10") or self.__hwModelCheck(version, "16,15"):
|
184
|
+
return "Mac mini (M4, 2024)"
|
175
185
|
if self.__hwModelCheck(version, "15,13"):
|
176
186
|
return "MacBook Air (15-inch, M3, 2024)"
|
177
187
|
if self.__hwModelCheck(version, "15,2"):
|
@@ -262,7 +272,7 @@ class HostDetectMacOS:
|
|
262
272
|
if self.__hwModelCheck(version, "9,1"):
|
263
273
|
return "iMac (24/20-inch, Early 2009)"
|
264
274
|
|
265
|
-
return
|
275
|
+
return hw_model
|
266
276
|
|
267
277
|
@staticmethod
|
268
278
|
def __hwModelCheck(version: str, target: str):
|
@@ -7,9 +7,7 @@ class KernelDetect:
|
|
7
7
|
self.OS = os
|
8
8
|
|
9
9
|
def getKernelInfo(self):
|
10
|
-
if self.OS
|
11
|
-
return KernelDetectUnix().getKernelInfo()
|
12
|
-
elif self.OS == "macos":
|
10
|
+
if self.OS in ["linux", "macos", "freebsd"]:
|
13
11
|
return KernelDetectUnix().getKernelInfo()
|
14
12
|
elif self.OS == "windows":
|
15
13
|
raise OSUnsupportedException("Unsupported operating system")
|
pyhw/backend/memory/linux.py
CHANGED
@@ -3,22 +3,22 @@ from .memoryInfo import MemoryInfo
|
|
3
3
|
|
4
4
|
class MemoryDetectLinux:
|
5
5
|
def __init__(self):
|
6
|
-
self.
|
6
|
+
self._memoryInfo = MemoryInfo()
|
7
7
|
|
8
8
|
def getMemoryInfo(self):
|
9
|
-
self.
|
10
|
-
self.
|
11
|
-
return self.
|
9
|
+
self._getMemory()
|
10
|
+
self._memoryInfo.memory = f"{self._memoryInfo.used} MiB / {self._memoryInfo.total} MiB"
|
11
|
+
return self._memoryInfo
|
12
12
|
|
13
|
-
def
|
13
|
+
def _getMemory(self):
|
14
14
|
try:
|
15
15
|
with open("/proc/meminfo", "r") as file:
|
16
16
|
for line in file:
|
17
17
|
if line.startswith("MemTotal:"):
|
18
|
-
self.
|
18
|
+
self._memoryInfo.total = round(float(line.split(":")[1].strip()[:-3]) / 1024, 2)
|
19
19
|
elif line.startswith("MemAvailable:"):
|
20
|
-
self.
|
21
|
-
self.
|
20
|
+
self._memoryInfo.available = round(float(line.split(":")[1].strip()[:-3]) / 1024, 2)
|
21
|
+
self._memoryInfo.used = round(self._memoryInfo.total - self._memoryInfo.available, 2)
|
22
22
|
except FileNotFoundError:
|
23
23
|
pass
|
24
24
|
|
@@ -1,5 +1,6 @@
|
|
1
1
|
from .linux import MemoryDetectLinux
|
2
2
|
from .macos import MemoryDetectMacOS
|
3
|
+
from .bsd import MemoryDetectBSD
|
3
4
|
|
4
5
|
|
5
6
|
class MemoryDetect:
|
@@ -11,5 +12,7 @@ class MemoryDetect:
|
|
11
12
|
return MemoryDetectLinux().getMemoryInfo()
|
12
13
|
elif self.OS == "macos":
|
13
14
|
return MemoryDetectMacOS().getMemoryInfo()
|
15
|
+
elif self.OS == "freebsd":
|
16
|
+
return MemoryDetectBSD().getMemoryInfo()
|
14
17
|
else:
|
15
18
|
raise NotImplementedError("Unsupported operating system")
|
pyhw/backend/nic/bsd.py
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
import subprocess
|
2
|
+
from .nicInfo import NICInfo
|
3
|
+
from ...pyhwUtil import getArch
|
4
|
+
from ...pyhwException import BackendException
|
5
|
+
import pypci
|
6
|
+
import os
|
7
|
+
|
8
|
+
|
9
|
+
class NICDetectLinux:
|
10
|
+
def __init__(self):
|
11
|
+
self._nicInfo = NICInfo()
|
12
|
+
|
13
|
+
def getNICInfo(self):
|
14
|
+
self._getNICInfo()
|
15
|
+
self._sortNICList()
|
16
|
+
return self._nicInfo
|
17
|
+
|
18
|
+
def _getNICInfo(self):
|
19
|
+
nic_devices = pypci.PCI().FindAllNIC()
|
20
|
+
if len(nic_devices) == 0:
|
21
|
+
self.__handleNonePciDevices()
|
22
|
+
else:
|
23
|
+
for device in nic_devices:
|
24
|
+
if device.subsystem_device_name != "":
|
25
|
+
device_name = f"{device.vendor_name} {device.device_name} ({device.subsystem_device_name})"
|
26
|
+
else:
|
27
|
+
device_name = f"{device.vendor_name} {device.device_name}"
|
28
|
+
self._nicInfo.nics.append(self._nicNameClean(device_name))
|
29
|
+
self._nicInfo.number += 1
|
30
|
+
|
31
|
+
def __handleNonePciDevices(self):
|
32
|
+
# need to update
|
33
|
+
interfaces = list()
|
34
|
+
for i in os.listdir('/sys/class/net/'):
|
35
|
+
if i == "lo":
|
36
|
+
continue
|
37
|
+
interfaces.append(i)
|
38
|
+
if len(interfaces) > 0:
|
39
|
+
for interface in interfaces:
|
40
|
+
try:
|
41
|
+
if_ip = subprocess.run(["bash", "-c", f"ip -4 addr show {interface} | grep inet | awk '{{print $2}}'"], capture_output=True, text=True).stdout.strip().split("/")[0]
|
42
|
+
self._nicInfo.nics.append(f"{interface} @ {if_ip}")
|
43
|
+
self._nicInfo.number += 1
|
44
|
+
except:
|
45
|
+
pass
|
46
|
+
else:
|
47
|
+
pass
|
48
|
+
if self._nicInfo.number == 0:
|
49
|
+
self._nicInfo.nics.append("Not found")
|
50
|
+
self._nicInfo.number = 1
|
51
|
+
|
52
|
+
@staticmethod
|
53
|
+
def _nicNameClean(nic_name: str):
|
54
|
+
nic_name_clean = nic_name.replace("Corporation ", "")
|
55
|
+
return nic_name_clean
|
56
|
+
|
57
|
+
def _sortNICList(self):
|
58
|
+
return self._nicInfo.nics.sort()
|
@@ -0,0 +1,27 @@
|
|
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
|
26
|
+
|
27
|
+
|
@@ -0,0 +1,25 @@
|
|
1
|
+
from .linux import NICDetectLinux
|
2
|
+
from .macos import NICDetectMacOS
|
3
|
+
from .bsd import NICDetectBSD
|
4
|
+
|
5
|
+
|
6
|
+
class NICDetect:
|
7
|
+
"""
|
8
|
+
Class for network interface (NIC) detection.
|
9
|
+
"""
|
10
|
+
def __init__(self, os):
|
11
|
+
self.OS = os
|
12
|
+
|
13
|
+
def getNICInfo(self):
|
14
|
+
"""
|
15
|
+
Detects the network interfaces (NICs) connected to the system.
|
16
|
+
:return: dataclass NICInfo, direct attr: nics
|
17
|
+
"""
|
18
|
+
if self.OS == "linux":
|
19
|
+
return NICDetectLinux().getNICInfo()
|
20
|
+
elif self.OS == "macos":
|
21
|
+
return NICDetectMacOS().getNICInfo()
|
22
|
+
elif self.OS == "freebsd":
|
23
|
+
return NICDetectBSD().getNICInfo()
|
24
|
+
else:
|
25
|
+
raise NotImplementedError("Unsupported operating system")
|