pyhw 0.2.0b0__py3-none-any.whl → 0.7.4__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- 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")
|