pyhw 0.1.3b0__py3-none-any.whl → 0.2.0b0__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- pyhw/__main__.py +16 -14
- pyhw/backend/cpu/cpuBase.py +3 -0
- pyhw/backend/cpu/cpuInfo.py +13 -0
- pyhw/backend/cpu/linux.py +3 -11
- pyhw/backend/cpu/macos.py +69 -0
- pyhw/backend/gpu/gpuBase.py +3 -0
- pyhw/backend/gpu/gpuInfo.py +8 -0
- pyhw/backend/gpu/linux.py +3 -9
- pyhw/backend/gpu/macos.py +63 -0
- pyhw/backend/host/hostBase.py +1 -1
- pyhw/backend/host/hostInfo.py +13 -0
- pyhw/backend/host/linux.py +2 -14
- pyhw/backend/host/macos.py +265 -1
- pyhw/backend/kernel/kernelBase.py +4 -4
- pyhw/backend/kernel/kernelInfo.py +10 -0
- pyhw/backend/kernel/{linux.py → unix.py} +3 -14
- pyhw/backend/memory/linux.py +2 -10
- pyhw/backend/memory/macos.py +56 -0
- pyhw/backend/memory/memoryBase.py +3 -0
- pyhw/backend/memory/memoryInfo.py +10 -0
- pyhw/backend/os/linux.py +2 -17
- pyhw/backend/os/macos.py +36 -0
- pyhw/backend/os/osBase.py +3 -0
- pyhw/backend/os/osInfo.py +17 -0
- pyhw/backend/uptime/linux.py +5 -10
- pyhw/backend/uptime/macos.py +40 -0
- pyhw/backend/uptime/uptimeBase.py +3 -0
- pyhw/backend/uptime/uptimeInfo.py +7 -0
- pyhw/frontend/frontendBase.py +1 -1
- pyhw/pyhwUtil/__init__.py +2 -1
- pyhw/pyhwUtil/pyhwUtil.py +18 -14
- pyhw/pyhwUtil/sysctlUtil.py +37 -0
- {pyhw-0.1.3b0.dist-info → pyhw-0.2.0b0.dist-info}/METADATA +7 -2
- {pyhw-0.1.3b0.dist-info → pyhw-0.2.0b0.dist-info}/RECORD +38 -26
- pyhw/backend/kernel/macos.py +0 -7
- {pyhw-0.1.3b0.dist-info → pyhw-0.2.0b0.dist-info}/LICENSE +0 -0
- {pyhw-0.1.3b0.dist-info → pyhw-0.2.0b0.dist-info}/WHEEL +0 -0
- {pyhw-0.1.3b0.dist-info → pyhw-0.2.0b0.dist-info}/entry_points.txt +0 -0
- {pyhw-0.1.3b0.dist-info → pyhw-0.2.0b0.dist-info}/top_level.txt +0 -0
pyhw/__main__.py
CHANGED
@@ -14,23 +14,25 @@ from .pyhwUtil import getOS, selectOSLogo
|
|
14
14
|
|
15
15
|
|
16
16
|
def main():
|
17
|
-
|
18
|
-
|
19
|
-
|
17
|
+
current_os = getOS()
|
18
|
+
print("This is a test version of PyHw. Currently, it only supports Linux and macOS.")
|
19
|
+
if current_os != "linux" and current_os != "macos":
|
20
|
+
print(f"Only Linux and macOS is supported for now. Current os: {current_os}")
|
20
21
|
return
|
21
22
|
data = Data()
|
22
|
-
data.title = TitleDetect(os=
|
23
|
-
data.Host = HostDetect(os=
|
24
|
-
data.Kernel = KernelDetect(os=
|
25
|
-
data.Shell = ShellDetect(os=
|
26
|
-
data.Uptime = UptimeDetect(os=
|
27
|
-
data.OS = OSDetect(os=
|
28
|
-
data.CPU = CPUDetect(os=
|
29
|
-
|
30
|
-
|
31
|
-
|
23
|
+
data.title = TitleDetect(os=current_os).getTitle().title
|
24
|
+
data.Host = HostDetect(os=current_os).getHostInfo().model
|
25
|
+
data.Kernel = KernelDetect(os=current_os).getKernelInfo().kernel
|
26
|
+
data.Shell = ShellDetect(os=current_os).getShellInfo().info
|
27
|
+
data.Uptime = UptimeDetect(os=current_os).getUptime().uptime
|
28
|
+
data.OS = OSDetect(os=current_os).getOSInfo().prettyName
|
29
|
+
data.CPU = CPUDetect(os=current_os).getCPUInfo().cpu
|
30
|
+
gpu_info = GPUDetect(os=current_os).getGPUInfo()
|
31
|
+
if gpu_info.number > 0:
|
32
|
+
data.GPU = gpu_info.gpus
|
33
|
+
data.Memory = MemoryDetect(os=current_os).getMemoryInfo().memory
|
32
34
|
|
33
|
-
Printer(logo_os=selectOSLogo(OSDetect(os=
|
35
|
+
Printer(logo_os=selectOSLogo(OSDetect(os=current_os).getOSInfo().id), data=createDataString(data)).cPrint()
|
34
36
|
|
35
37
|
|
36
38
|
if __name__ == "__main__":
|
pyhw/backend/cpu/cpuBase.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
from .linux import CPUDetectLinux
|
2
|
+
from .macos import CPUDetectMacOS
|
2
3
|
from ...pyhwException import OSUnsupportedException
|
3
4
|
|
4
5
|
|
@@ -9,5 +10,7 @@ class CPUDetect:
|
|
9
10
|
def getCPUInfo(self):
|
10
11
|
if self.OS == "linux":
|
11
12
|
return CPUDetectLinux().getCPUInfo()
|
13
|
+
elif self.OS == "macos":
|
14
|
+
return CPUDetectMacOS().getCPUInfo()
|
12
15
|
else:
|
13
16
|
raise OSUnsupportedException("Unsupported operating system")
|
pyhw/backend/cpu/linux.py
CHANGED
@@ -1,19 +1,11 @@
|
|
1
|
-
from dataclasses import dataclass
|
2
1
|
import re
|
3
2
|
import os
|
4
|
-
|
5
|
-
|
6
|
-
@dataclass
|
7
|
-
class CPUInfoLinux:
|
8
|
-
cpu = ""
|
9
|
-
model = ""
|
10
|
-
cores = ""
|
11
|
-
frequency = ""
|
3
|
+
from .cpuInfo import CPUInfo
|
12
4
|
|
13
5
|
|
14
6
|
class CPUDetectLinux:
|
15
7
|
def __init__(self):
|
16
|
-
self.__cpuInfo =
|
8
|
+
self.__cpuInfo = CPUInfo()
|
17
9
|
|
18
10
|
def getCPUInfo(self):
|
19
11
|
self.__getCPUInfo()
|
@@ -53,7 +45,7 @@ class CPUDetectLinux:
|
|
53
45
|
else:
|
54
46
|
for line in cpu_info.split("\n"):
|
55
47
|
if line.startswith("cpu MHz") or line.startswith("clock"):
|
56
|
-
self.__cpuInfo.frequency = float(line.split(
|
48
|
+
self.__cpuInfo.frequency = f"{round(float(line.split(':')[1].strip()) / 1000, 2)} Ghz" # Ghz
|
57
49
|
break
|
58
50
|
|
59
51
|
def __modelClean(self):
|
@@ -0,0 +1,69 @@
|
|
1
|
+
from .cpuInfo import CPUInfo
|
2
|
+
from ...pyhwUtil import sysctlGetString, sysctlGetInt, getArch
|
3
|
+
|
4
|
+
|
5
|
+
class CPUDetectMacOS:
|
6
|
+
def __init__(self):
|
7
|
+
self.__cpuInfo = CPUInfo()
|
8
|
+
self.__arch = getArch()
|
9
|
+
self.__pCore = 0
|
10
|
+
self.__eCore = 0
|
11
|
+
|
12
|
+
def getCPUInfo(self):
|
13
|
+
if self.__arch == "aarch64":
|
14
|
+
self.__getCPUModel()
|
15
|
+
self.__AppleSiliconBaseFrequency()
|
16
|
+
self.__handleAppleSilicon()
|
17
|
+
self.__cpuInfo.cpu = f"{self.__cpuInfo.model} ({self.__pCore}P, {self.__eCore}E) @ {self.__cpuInfo.frequency}"
|
18
|
+
else:
|
19
|
+
self.__getCPUModel()
|
20
|
+
self.__getCPUCores()
|
21
|
+
self.__getCPUFrequency()
|
22
|
+
# need test on Intel Macs.
|
23
|
+
self.__cpuInfo.cpu = f"{self.__cpuInfo.model.replace('CPU', f'({self.__cpuInfo.cores})')}"
|
24
|
+
return self.__cpuInfo
|
25
|
+
|
26
|
+
def __getCPUModel(self):
|
27
|
+
model = sysctlGetString("machdep.cpu.brand_string")
|
28
|
+
model = model.replace("(R)", "")
|
29
|
+
model = model.replace("(TM)", "")
|
30
|
+
self.__cpuInfo.model = model
|
31
|
+
|
32
|
+
def __getCPUCores(self):
|
33
|
+
cores = sysctlGetString("hw.logicalcpu_max")
|
34
|
+
self.__cpuInfo.cores = cores
|
35
|
+
|
36
|
+
def __getCPUFrequency(self):
|
37
|
+
# sysctl doesn't provide the exact CPU frequency on Apple Silicon Macs, there are some indirect methods
|
38
|
+
# to get the CPU frequency, but can not integrate with Python directly.
|
39
|
+
# C-Based helper module will be added later.
|
40
|
+
# See https://github.com/fastfetch-cli/fastfetch/blob/dev/src/detection/cpu/cpu_apple.c for more details.
|
41
|
+
freq = sysctlGetString("hw.cpufrequency")
|
42
|
+
self.__cpuInfo.frequency = freq
|
43
|
+
|
44
|
+
def __handleAppleSilicon(self):
|
45
|
+
nlevels = sysctlGetInt("hw.nperflevels")
|
46
|
+
if nlevels is not None and nlevels == 2: # currently, Apple Silicon chip only has 2 performance levels.
|
47
|
+
pcore = sysctlGetInt("hw.perflevel0.logicalcpu_max") # level 0 is P-core
|
48
|
+
ecore = sysctlGetInt("hw.perflevel1.logicalcpu_max") # level 1 is E-core
|
49
|
+
if pcore is not None and ecore is not None:
|
50
|
+
self.__pCore = pcore
|
51
|
+
self.__eCore = ecore
|
52
|
+
|
53
|
+
def __AppleSiliconBaseFrequency(self):
|
54
|
+
# see https://en.wikipedia.org/wiki/Apple_silicon#M_series for more details.
|
55
|
+
freq = {
|
56
|
+
"Apple M1": "2.30 GHz",
|
57
|
+
"Apple M1 Pro": "2.32 GHz",
|
58
|
+
"Apple M1 Max": "2.32 GHz",
|
59
|
+
"Apple M1 Ultra": "2.32 GHz",
|
60
|
+
"Apple M2": "3.50 GHz",
|
61
|
+
"Apple M2 Pro": "3.50 GHz",
|
62
|
+
"Apple M2 Max": "3.69 GHz",
|
63
|
+
"Apple M2 Ultra": "3.70 Ghz",
|
64
|
+
"Apple M3": "4.05 GHz",
|
65
|
+
"Apple M3 Pro": "4.05 GHz",
|
66
|
+
"Apple M3 Max": "4.05 GHz",
|
67
|
+
"Apple M4": "4.40 GHz"
|
68
|
+
}
|
69
|
+
self.__cpuInfo.frequency = freq.get(self.__cpuInfo.model, "Unknown")
|
pyhw/backend/gpu/gpuBase.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
from .linux import GPUDetectLinux
|
2
|
+
from .macos import GPUDetectMacOS
|
2
3
|
|
3
4
|
|
4
5
|
class GPUDetect:
|
@@ -8,5 +9,7 @@ class GPUDetect:
|
|
8
9
|
def getGPUInfo(self):
|
9
10
|
if self.OS == "linux":
|
10
11
|
return GPUDetectLinux().getGPUInfo()
|
12
|
+
elif self.OS == "macos":
|
13
|
+
return GPUDetectMacOS().getGPUInfo()
|
11
14
|
else:
|
12
15
|
raise NotImplementedError("Unsupported operating system")
|
pyhw/backend/gpu/linux.py
CHANGED
@@ -1,18 +1,12 @@
|
|
1
1
|
import subprocess
|
2
|
-
from
|
2
|
+
from .gpuInfo import GPUInfo
|
3
3
|
from ..cpu import CPUDetect
|
4
4
|
from ...pyhwUtil import getArch
|
5
5
|
|
6
6
|
|
7
|
-
@dataclass
|
8
|
-
class GPUInfoLinux:
|
9
|
-
number = 0
|
10
|
-
gpus = []
|
11
|
-
|
12
|
-
|
13
7
|
class GPUDetectLinux:
|
14
8
|
def __init__(self):
|
15
|
-
self.__gpuInfo =
|
9
|
+
self.__gpuInfo = GPUInfo()
|
16
10
|
|
17
11
|
def getGPUInfo(self):
|
18
12
|
self.__getGPUInfo()
|
@@ -37,7 +31,7 @@ class GPUDetectLinux:
|
|
37
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.
|
38
32
|
if getArch() == "aarch64" or getArch() == "arm32":
|
39
33
|
self.__gpuInfo.number = 1
|
40
|
-
self.__gpuInfo.gpus.append(f"{CPUDetect(os='linux').getCPUInfo().model}
|
34
|
+
self.__gpuInfo.gpus.append(f"{CPUDetect(os='linux').getCPUInfo().model} [SOC Integrated]")
|
41
35
|
else:
|
42
36
|
self.__gpuInfo.number = 1
|
43
37
|
self.__gpuInfo.gpus.append("Not found")
|
@@ -0,0 +1,63 @@
|
|
1
|
+
from .gpuInfo import GPUInfo
|
2
|
+
from ...pyhwUtil import getArch
|
3
|
+
import json
|
4
|
+
import subprocess
|
5
|
+
|
6
|
+
|
7
|
+
class GPUDetectMacOS:
|
8
|
+
def __init__(self):
|
9
|
+
self.__gpuInfo = GPUInfo()
|
10
|
+
self.__arch = getArch()
|
11
|
+
|
12
|
+
def getGPUInfo(self):
|
13
|
+
if self.__arch == "aarch64":
|
14
|
+
self.__getGPUAppleSilicon()
|
15
|
+
else: # Does not consider powerPC based Macs.
|
16
|
+
self.__getGPUIntel()
|
17
|
+
return self.__gpuInfo
|
18
|
+
|
19
|
+
def __getGPUAppleSilicon(self):
|
20
|
+
gpus = list()
|
21
|
+
try:
|
22
|
+
gpu_info_dict = json.loads(subprocess.check_output(["system_profiler", "SPDisplaysDataType", "-json"]))
|
23
|
+
if 'SPDisplaysDataType' in gpu_info_dict:
|
24
|
+
gpus = gpu_info_dict['SPDisplaysDataType']
|
25
|
+
self.__gpuInfo.number = len(gpus)
|
26
|
+
else:
|
27
|
+
pass
|
28
|
+
except Exception:
|
29
|
+
return
|
30
|
+
|
31
|
+
for gpu in gpus:
|
32
|
+
self.__gpuInfo.gpus.append(f'{gpu.get("sppci_model")} ({gpu.get("sppci_cores")} cores) [SOC Integrated]')
|
33
|
+
|
34
|
+
def __getGPUIntel(self):
|
35
|
+
gpus = list()
|
36
|
+
try:
|
37
|
+
gpu_info_dict = json.loads(subprocess.check_output(["system_profiler", "SPDisplaysDataType", "-json"]))
|
38
|
+
if 'SPDisplaysDataType' in gpu_info_dict:
|
39
|
+
gpus = gpu_info_dict['SPDisplaysDataType']
|
40
|
+
self.__gpuInfo.number = len(gpus)
|
41
|
+
else:
|
42
|
+
pass
|
43
|
+
except Exception:
|
44
|
+
return
|
45
|
+
|
46
|
+
for gpu in gpus:
|
47
|
+
if self.__handleVendor(gpu.get("spdisplays_vendor")) == "Intel": # Integrated GPU
|
48
|
+
self.__gpuInfo.gpus.append(f'{gpu.get("sppci_model")} [CPU Integrated]')
|
49
|
+
elif self.__handleVendor(gpu.get("spdisplays_vendor")) == "AMD": # dGPU
|
50
|
+
self.__gpuInfo.gpus.append(f'{gpu.get("sppci_model")} [Discrete]')
|
51
|
+
elif self.__handleVendor(gpu.get("spdisplays_vendor")) == "Nvidia": # Since current macOS does not support NVIDIA GPUs, this condition is not applicable
|
52
|
+
pass
|
53
|
+
|
54
|
+
@staticmethod
|
55
|
+
def __handleVendor(vendor):
|
56
|
+
if vendor == "sppci_vendor_Apple":
|
57
|
+
return "Apple"
|
58
|
+
elif vendor == "sppci_vendor_intel":
|
59
|
+
return "Intel"
|
60
|
+
elif vendor == "sppci_vendor_amd":
|
61
|
+
return "AMD"
|
62
|
+
else:
|
63
|
+
return vendor
|
pyhw/backend/host/hostBase.py
CHANGED
pyhw/backend/host/linux.py
CHANGED
@@ -2,24 +2,12 @@
|
|
2
2
|
In dev.
|
3
3
|
"""
|
4
4
|
from ...pyhwUtil import getArch
|
5
|
-
from
|
6
|
-
|
7
|
-
|
8
|
-
@dataclass
|
9
|
-
class HostInfoLinux:
|
10
|
-
model = ""
|
11
|
-
family = ""
|
12
|
-
name = ""
|
13
|
-
version = ""
|
14
|
-
sku = ""
|
15
|
-
serial = ""
|
16
|
-
uuid = ""
|
17
|
-
vendor = ""
|
5
|
+
from .hostInfo import HostInfo
|
18
6
|
|
19
7
|
|
20
8
|
class HostDetectLinux:
|
21
9
|
def __init__(self):
|
22
|
-
self.__hostInfo =
|
10
|
+
self.__hostInfo = HostInfo()
|
23
11
|
self.__arch = getArch()
|
24
12
|
|
25
13
|
def getHostInfo(self):
|
pyhw/backend/host/macos.py
CHANGED
@@ -1,5 +1,269 @@
|
|
1
1
|
"""
|
2
2
|
In dev.
|
3
3
|
"""
|
4
|
+
from .hostInfo import HostInfo
|
5
|
+
from ...pyhwUtil import sysctlGetString
|
6
|
+
|
7
|
+
|
4
8
|
class HostDetectMacOS:
|
5
|
-
|
9
|
+
def __init__(self):
|
10
|
+
self.__hostInfo = HostInfo()
|
11
|
+
self.__HWModel = ""
|
12
|
+
|
13
|
+
def getHostInfo(self):
|
14
|
+
self.__getHWModel()
|
15
|
+
self.__hostInfo.model = self.__handleMacName(self.__HWModel)
|
16
|
+
return self.__hostInfo
|
17
|
+
|
18
|
+
def __getHWModel(self):
|
19
|
+
self.__HWModel = sysctlGetString("hw.model")
|
20
|
+
|
21
|
+
def __handleMacName(self, hw_model: str):
|
22
|
+
# This part of the code is directly re-implemented from the fastfetch project. It seems that there is no
|
23
|
+
# more elegant way to get the product name of the Mac.
|
24
|
+
# See https://github.com/fastfetch-cli/fastfetch/blob/dev/src/detection/host/host_apple.c for more details.
|
25
|
+
if hw_model.startswith("MacBookPro"):
|
26
|
+
version = hw_model[len("MacBookPro"):]
|
27
|
+
if self.__hwModelCheck(version, "18,3") or self.__hwModelCheck(version, "18,4"):
|
28
|
+
return "MacBook Pro (14-inch, 2021)"
|
29
|
+
if self.__hwModelCheck(version, "18,1") or self.__hwModelCheck(version, "18,2"):
|
30
|
+
return "MacBook Pro (16-inch, 2021)"
|
31
|
+
if self.__hwModelCheck(version, "17,1"):
|
32
|
+
return "MacBook Pro (13-inch, M1, 2020)"
|
33
|
+
if self.__hwModelCheck(version, "16,3"):
|
34
|
+
return "MacBook Pro (13-inch, 2020, Two Thunderbolt 3 ports)"
|
35
|
+
if self.__hwModelCheck(version, "16,2"):
|
36
|
+
return "MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports)"
|
37
|
+
if self.__hwModelCheck(version, "16,4") or self.__hwModelCheck(version, "16,1"):
|
38
|
+
return "MacBook Pro (16-inch, 2019)"
|
39
|
+
if self.__hwModelCheck(version, "15,4"):
|
40
|
+
return "MacBook Pro (13-inch, 2019, Two Thunderbolt 3 ports)"
|
41
|
+
if self.__hwModelCheck(version, "15,3"):
|
42
|
+
return "MacBook Pro (15-inch, 2019)"
|
43
|
+
if self.__hwModelCheck(version, "15,2"):
|
44
|
+
return "MacBook Pro (13-inch, 2018/2019, Four Thunderbolt 3 ports)"
|
45
|
+
if self.__hwModelCheck(version, "15,1"):
|
46
|
+
return "MacBook Pro (15-inch, 2018/2019)"
|
47
|
+
if self.__hwModelCheck(version, "14,3"):
|
48
|
+
return "MacBook Pro (15-inch, 2017)"
|
49
|
+
if self.__hwModelCheck(version, "14,2"):
|
50
|
+
return "MacBook Pro (13-inch, 2017, Four Thunderbolt 3 ports)"
|
51
|
+
if self.__hwModelCheck(version, "14,1"):
|
52
|
+
return "MacBook Pro (13-inch, 2017, Two Thunderbolt 3 ports)"
|
53
|
+
if self.__hwModelCheck(version, "13,3"):
|
54
|
+
return "MacBook Pro (15-inch, 2016)"
|
55
|
+
if self.__hwModelCheck(version, "13,2"):
|
56
|
+
return "MacBook Pro (13-inch, 2016, Four Thunderbolt 3 ports)"
|
57
|
+
if self.__hwModelCheck(version, "13,1"):
|
58
|
+
return "MacBook Pro (13-inch, 2016, Two Thunderbolt 3 ports)"
|
59
|
+
if self.__hwModelCheck(version, "12,1"):
|
60
|
+
return "MacBook Pro (Retina, 13-inch, Early 2015)"
|
61
|
+
if self.__hwModelCheck(version, "11,4") or self.__hwModelCheck(version, "11,5"):
|
62
|
+
return "MacBook Pro (Retina, 15-inch, Mid 2015)"
|
63
|
+
if self.__hwModelCheck(version, "11,2") or self.__hwModelCheck(version, "11,3"):
|
64
|
+
return "MacBook Pro (Retina, 15-inch, Late 2013/Mid 2014)"
|
65
|
+
if self.__hwModelCheck(version, "11,1"):
|
66
|
+
return "MacBook Pro (Retina, 13-inch, Late 2013/Mid 2014)"
|
67
|
+
if self.__hwModelCheck(version, "10,2"):
|
68
|
+
return "MacBook Pro (Retina, 13-inch, Late 2012/Early 2013)"
|
69
|
+
if self.__hwModelCheck(version, "10,1"):
|
70
|
+
return "MacBook Pro (Retina, 15-inch, Mid 2012/Early 2013)"
|
71
|
+
if self.__hwModelCheck(version, "9,2"):
|
72
|
+
return "MacBook Pro (13-inch, Mid 2012)"
|
73
|
+
if self.__hwModelCheck(version, "9,1"):
|
74
|
+
return "MacBook Pro (15-inch, Mid 2012)"
|
75
|
+
if self.__hwModelCheck(version, "8,3"):
|
76
|
+
return "MacBook Pro (17-inch, 2011)"
|
77
|
+
if self.__hwModelCheck(version, "8,2"):
|
78
|
+
return "MacBook Pro (15-inch, 2011)"
|
79
|
+
if self.__hwModelCheck(version, "8,1"):
|
80
|
+
return "MacBook Pro (13-inch, 2011)"
|
81
|
+
if self.__hwModelCheck(version, "7,1"):
|
82
|
+
return "MacBook Pro (13-inch, Mid 2010)"
|
83
|
+
if self.__hwModelCheck(version, "6,2"):
|
84
|
+
return "MacBook Pro (15-inch, Mid 2010)"
|
85
|
+
if self.__hwModelCheck(version, "6,1"):
|
86
|
+
return "MacBook Pro (17-inch, Mid 2010)"
|
87
|
+
if self.__hwModelCheck(version, "5,5"):
|
88
|
+
return "MacBook Pro (13-inch, Mid 2009)"
|
89
|
+
if self.__hwModelCheck(version, "5,3"):
|
90
|
+
return "MacBook Pro (15-inch, Mid 2009)"
|
91
|
+
if self.__hwModelCheck(version, "5,2"):
|
92
|
+
return "MacBook Pro (17-inch, Mid/Early 2009)"
|
93
|
+
if self.__hwModelCheck(version, "5,1"):
|
94
|
+
return "MacBook Pro (15-inch, Late 2008)"
|
95
|
+
if self.__hwModelCheck(version, "4,1"):
|
96
|
+
return "MacBook Pro (17/15-inch, Early 2008)"
|
97
|
+
elif hw_model.startswith("MacBookAir"):
|
98
|
+
version = hw_model[len("MacBookAir"):]
|
99
|
+
if self.__hwModelCheck(version, "10,1"):
|
100
|
+
return "MacBook Air (M1, 2020)"
|
101
|
+
if self.__hwModelCheck(version, "9,1"):
|
102
|
+
return "MacBook Air (Retina, 13-inch, 2020)"
|
103
|
+
if self.__hwModelCheck(version, "8,2"):
|
104
|
+
return "MacBook Air (Retina, 13-inch, 2019)"
|
105
|
+
if self.__hwModelCheck(version, "8,1"):
|
106
|
+
return "MacBook Air (Retina, 13-inch, 2018)"
|
107
|
+
if self.__hwModelCheck(version, "7,2"):
|
108
|
+
return "MacBook Air (13-inch, Early 2015/2017)"
|
109
|
+
if self.__hwModelCheck(version, "7,1"):
|
110
|
+
return "MacBook Air (11-inch, Early 2015)"
|
111
|
+
if self.__hwModelCheck(version, "6,2"):
|
112
|
+
return "MacBook Air (13-inch, Mid 2013/Early 2014)"
|
113
|
+
if self.__hwModelCheck(version, "6,1"):
|
114
|
+
return "MacBook Air (11-inch, Mid 2013/Early 2014)"
|
115
|
+
if self.__hwModelCheck(version, "5,2"):
|
116
|
+
return "MacBook Air (13-inch, Mid 2012)"
|
117
|
+
if self.__hwModelCheck(version, "5,1"):
|
118
|
+
return "MacBook Air (11-inch, Mid 2012)"
|
119
|
+
if self.__hwModelCheck(version, "4,2"):
|
120
|
+
return "MacBook Air (13-inch, Mid 2011)"
|
121
|
+
if self.__hwModelCheck(version, "4,1"):
|
122
|
+
return "MacBook Air (11-inch, Mid 2011)"
|
123
|
+
if self.__hwModelCheck(version, "3,2"):
|
124
|
+
return "MacBook Air (13-inch, Late 2010)"
|
125
|
+
if self.__hwModelCheck(version, "3,1"):
|
126
|
+
return "MacBook Air (11-inch, Late 2010)"
|
127
|
+
if self.__hwModelCheck(version, "2,1"):
|
128
|
+
return "MacBook Air (Mid 2009)"
|
129
|
+
|
130
|
+
elif hw_model.startswith("Macmini"):
|
131
|
+
version = hw_model[len("Macmini"):]
|
132
|
+
if self.__hwModelCheck(version, "9,1"):
|
133
|
+
return "Mac mini (M1, 2020)"
|
134
|
+
if self.__hwModelCheck(version, "8,1"):
|
135
|
+
return "Mac mini (2018)"
|
136
|
+
if self.__hwModelCheck(version, "7,1"):
|
137
|
+
return "Mac mini (Mid 2014)"
|
138
|
+
if self.__hwModelCheck(version, "6,1") or self.__hwModelCheck(version, "6,2"):
|
139
|
+
return "Mac mini (Late 2012)"
|
140
|
+
if self.__hwModelCheck(version, "5,1") or self.__hwModelCheck(version, "5,2"):
|
141
|
+
return "Mac mini (Mid 2011)"
|
142
|
+
if self.__hwModelCheck(version, "4,1"):
|
143
|
+
return "Mac mini (Mid 2010)"
|
144
|
+
if self.__hwModelCheck(version, "3,1"):
|
145
|
+
return "Mac mini (Early/Late 2009)"
|
146
|
+
|
147
|
+
elif hw_model.startswith("MacBook"):
|
148
|
+
version = hw_model[len("MacBook"):]
|
149
|
+
if self.__hwModelCheck(version, "10,1"):
|
150
|
+
return "MacBook (Retina, 12-inch, 2017)"
|
151
|
+
if self.__hwModelCheck(version, "9,1"):
|
152
|
+
return "MacBook (Retina, 12-inch, Early 2016)"
|
153
|
+
if self.__hwModelCheck(version, "8,1"):
|
154
|
+
return "MacBook (Retina, 12-inch, Early 2015)"
|
155
|
+
if self.__hwModelCheck(version, "7,1"):
|
156
|
+
return "MacBook (13-inch, Mid 2010)"
|
157
|
+
if self.__hwModelCheck(version, "6,1"):
|
158
|
+
return "MacBook (13-inch, Late 2009)"
|
159
|
+
if self.__hwModelCheck(version, "5,2"):
|
160
|
+
return "MacBook (13-inch, Early/Mid 2009)"
|
161
|
+
|
162
|
+
elif hw_model.startswith("MacPro"):
|
163
|
+
version = hw_model[len("MacPro"):]
|
164
|
+
if self.__hwModelCheck(version, "7,1"):
|
165
|
+
return "Mac Pro (2019)"
|
166
|
+
if self.__hwModelCheck(version, "6,1"):
|
167
|
+
return "Mac Pro (Late 2013)"
|
168
|
+
if self.__hwModelCheck(version, "5,1"):
|
169
|
+
return "Mac Pro (Mid 2010 - Mid 2012)"
|
170
|
+
if self.__hwModelCheck(version, "4,1"):
|
171
|
+
return "Mac Pro (Early 2009)"
|
172
|
+
|
173
|
+
elif hw_model.startswith("Mac"):
|
174
|
+
version = hw_model[len("Mac"):]
|
175
|
+
if self.__hwModelCheck(version, "15,13"):
|
176
|
+
return "MacBook Air (15-inch, M3, 2024)"
|
177
|
+
if self.__hwModelCheck(version, "15,2"):
|
178
|
+
return "MacBook Air (13-inch, M3, 2024)"
|
179
|
+
if self.__hwModelCheck(version, "15,3"):
|
180
|
+
return "MacBook Pro (14-inch, Nov 2023, Two Thunderbolt / USB 4 ports)"
|
181
|
+
if self.__hwModelCheck(version, "15,4"):
|
182
|
+
return "iMac (24-inch, 2023, Two Thunderbolt / USB 4 ports)"
|
183
|
+
if self.__hwModelCheck(version, "15,5"):
|
184
|
+
return "iMac (24-inch, 2023, Two Thunderbolt / USB 4 ports, Two USB 3 ports)"
|
185
|
+
if self.__hwModelCheck(version, "15,6") or self.__hwModelCheck(version, "15,8") or self.__hwModelCheck(version, "15,10"):
|
186
|
+
return "MacBook Pro (14-inch, Nov 2023, Three Thunderbolt 4 ports)"
|
187
|
+
if self.__hwModelCheck(version, "15,7") or self.__hwModelCheck(version, "15,9") or self.__hwModelCheck(version, "15,11"):
|
188
|
+
return "MacBook Pro (16-inch, Nov 2023, Three Thunderbolt 4 ports)"
|
189
|
+
if self.__hwModelCheck(version, "14,15"):
|
190
|
+
return "MacBook Air (15-inch, M2, 2023)"
|
191
|
+
if self.__hwModelCheck(version, "14,14"):
|
192
|
+
return "Mac Studio (M2 Ultra, 2023, Two Thunderbolt 4 front ports)"
|
193
|
+
if self.__hwModelCheck(version, "14,13"):
|
194
|
+
return "Mac Studio (M2 Max, 2023, Two USB-C front ports)"
|
195
|
+
if self.__hwModelCheck(version, "14,8"):
|
196
|
+
return "Mac Pro (2023)"
|
197
|
+
if self.__hwModelCheck(version, "14,6") or self.__hwModelCheck(version, "14,10"):
|
198
|
+
return "MacBook Pro (16-inch, 2023)"
|
199
|
+
if self.__hwModelCheck(version, "14,5") or self.__hwModelCheck(version, "14,9"):
|
200
|
+
return "MacBook Pro (14-inch, 2023)"
|
201
|
+
if self.__hwModelCheck(version, "14,3"):
|
202
|
+
return "Mac mini (M2, 2023, Two Thunderbolt 4 ports)"
|
203
|
+
if self.__hwModelCheck(version, "14,12"):
|
204
|
+
return "Mac mini (M2, 2023, Four Thunderbolt 4 ports)"
|
205
|
+
if self.__hwModelCheck(version, "14,7"):
|
206
|
+
return "MacBook Pro (13-inch, M2, 2022)"
|
207
|
+
if self.__hwModelCheck(version, "14,2"):
|
208
|
+
return "MacBook Air (M2, 2022)"
|
209
|
+
if self.__hwModelCheck(version, "13,1"):
|
210
|
+
return "Mac Studio (M1 Max, 2022, Two USB-C front ports)"
|
211
|
+
if self.__hwModelCheck(version, "13,2"):
|
212
|
+
return "Mac Studio (M1 Ultra, 2022, Two Thunderbolt 4 front ports)"
|
213
|
+
|
214
|
+
elif hw_model.startswith("iMac"):
|
215
|
+
version = hw_model[len("iMac"):]
|
216
|
+
if self.__hwModelCheck(version, "21,1"):
|
217
|
+
return "iMac (24-inch, M1, 2021, Two Thunderbolt / USB 4 ports, Two USB 3 ports)"
|
218
|
+
if self.__hwModelCheck(version, "21,2"):
|
219
|
+
return "iMac (24-inch, M1, 2021, Two Thunderbolt / USB 4 ports)"
|
220
|
+
if self.__hwModelCheck(version, "20,1") or self.__hwModelCheck(version, "20,2"):
|
221
|
+
return "iMac (Retina 5K, 27-inch, 2020)"
|
222
|
+
if self.__hwModelCheck(version, "19,1"):
|
223
|
+
return "iMac (Retina 5K, 27-inch, 2019)"
|
224
|
+
if self.__hwModelCheck(version, "19,2"):
|
225
|
+
return "iMac (Retina 4K, 21.5-inch, 2019)"
|
226
|
+
if self.__hwModelCheck(version, "Pro1,1"):
|
227
|
+
return "iMac Pro (2017)"
|
228
|
+
if self.__hwModelCheck(version, "18,3"):
|
229
|
+
return "iMac (Retina 5K, 27-inch, 2017)"
|
230
|
+
if self.__hwModelCheck(version, "18,2"):
|
231
|
+
return "iMac (Retina 4K, 21.5-inch, 2017)"
|
232
|
+
if self.__hwModelCheck(version, "18,1"):
|
233
|
+
return "iMac (21.5-inch, 2017)"
|
234
|
+
if self.__hwModelCheck(version, "17,1"):
|
235
|
+
return "iMac (Retina 5K, 27-inch, Late 2015)"
|
236
|
+
if self.__hwModelCheck(version, "16,2"):
|
237
|
+
return "iMac (Retina 4K, 21.5-inch, Late 2015)"
|
238
|
+
if self.__hwModelCheck(version, "16,1"):
|
239
|
+
return "iMac (21.5-inch, Late 2015)"
|
240
|
+
if self.__hwModelCheck(version, "15,1"):
|
241
|
+
return "iMac (Retina 5K, 27-inch, Late 2014 - Mid 2015)"
|
242
|
+
if self.__hwModelCheck(version, "14,4"):
|
243
|
+
return "iMac (21.5-inch, Mid 2014)"
|
244
|
+
if self.__hwModelCheck(version, "14,2"):
|
245
|
+
return "iMac (27-inch, Late 2013)"
|
246
|
+
if self.__hwModelCheck(version, "14,1"):
|
247
|
+
return "iMac (21.5-inch, Late 2013)"
|
248
|
+
if self.__hwModelCheck(version, "13,2"):
|
249
|
+
return "iMac (27-inch, Late 2012)"
|
250
|
+
if self.__hwModelCheck(version, "13,1"):
|
251
|
+
return "iMac (21.5-inch, Late 2012)"
|
252
|
+
if self.__hwModelCheck(version, "12,2"):
|
253
|
+
return "iMac (27-inch, Mid 2011)"
|
254
|
+
if self.__hwModelCheck(version, "12,1"):
|
255
|
+
return "iMac (21.5-inch, Mid 2011)"
|
256
|
+
if self.__hwModelCheck(version, "11,3"):
|
257
|
+
return "iMac (27-inch, Mid 2010)"
|
258
|
+
if self.__hwModelCheck(version, "11,2"):
|
259
|
+
return "iMac (21.5-inch, Mid 2010)"
|
260
|
+
if self.__hwModelCheck(version, "10,1"):
|
261
|
+
return "iMac (27/21.5-inch, Late 2009)"
|
262
|
+
if self.__hwModelCheck(version, "9,1"):
|
263
|
+
return "iMac (24/20-inch, Early 2009)"
|
264
|
+
|
265
|
+
return "Unknown Mac Model"
|
266
|
+
|
267
|
+
@staticmethod
|
268
|
+
def __hwModelCheck(version: str, target: str):
|
269
|
+
return version == target
|
@@ -1,4 +1,4 @@
|
|
1
|
-
from .
|
1
|
+
from .unix import KernelDetectUnix
|
2
2
|
from ...pyhwException import OSUnsupportedException
|
3
3
|
|
4
4
|
|
@@ -8,10 +8,10 @@ class KernelDetect:
|
|
8
8
|
|
9
9
|
def getKernelInfo(self):
|
10
10
|
if self.OS == "linux":
|
11
|
-
return
|
11
|
+
return KernelDetectUnix().getKernelInfo()
|
12
12
|
elif self.OS == "macos":
|
13
|
-
|
13
|
+
return KernelDetectUnix().getKernelInfo()
|
14
14
|
elif self.OS == "windows":
|
15
|
-
|
15
|
+
raise OSUnsupportedException("Unsupported operating system")
|
16
16
|
else:
|
17
17
|
raise OSUnsupportedException("Unsupported operating system")
|
@@ -1,21 +1,10 @@
|
|
1
|
-
|
2
|
-
In dev.
|
3
|
-
"""
|
4
|
-
from dataclasses import dataclass
|
1
|
+
from .kernelInfo import KernelInfo
|
5
2
|
import subprocess
|
6
3
|
|
7
4
|
|
8
|
-
|
9
|
-
class KernelInfoLinux:
|
10
|
-
name = ""
|
11
|
-
version = ""
|
12
|
-
machine = ""
|
13
|
-
kernel = ""
|
14
|
-
|
15
|
-
|
16
|
-
class KernelDetectLinux:
|
5
|
+
class KernelDetectUnix:
|
17
6
|
def __init__(self):
|
18
|
-
self.__kernelInfo =
|
7
|
+
self.__kernelInfo = KernelInfo()
|
19
8
|
|
20
9
|
def getKernelInfo(self):
|
21
10
|
self.__getKernelName()
|
pyhw/backend/memory/linux.py
CHANGED
@@ -1,17 +1,9 @@
|
|
1
|
-
from
|
2
|
-
|
3
|
-
|
4
|
-
@dataclass
|
5
|
-
class MemoryInfoLinux:
|
6
|
-
memory = ""
|
7
|
-
total = 0
|
8
|
-
available = 0
|
9
|
-
used = 0
|
1
|
+
from .memoryInfo import MemoryInfo
|
10
2
|
|
11
3
|
|
12
4
|
class MemoryDetectLinux:
|
13
5
|
def __init__(self):
|
14
|
-
self.__memoryInfo =
|
6
|
+
self.__memoryInfo = MemoryInfo()
|
15
7
|
|
16
8
|
def getMemoryInfo(self):
|
17
9
|
self.__getMemory()
|
@@ -0,0 +1,56 @@
|
|
1
|
+
from .memoryInfo import MemoryInfo
|
2
|
+
from ...pyhwUtil import sysctlGetInt
|
3
|
+
import subprocess
|
4
|
+
|
5
|
+
|
6
|
+
class MemoryDetectMacOS:
|
7
|
+
def __init__(self):
|
8
|
+
self.__memoryInfo = MemoryInfo()
|
9
|
+
self.__hw_pagesize = 0
|
10
|
+
self.__mem_total = 0
|
11
|
+
self.__active_count = 0
|
12
|
+
self.__inactive_count = 0
|
13
|
+
self.__speculative_count = 0
|
14
|
+
self.__wire_count = 0
|
15
|
+
self.__compressor_page_count = 0
|
16
|
+
self.__purgeable_count = 0
|
17
|
+
self.__external_page_count = 0
|
18
|
+
self.__mem_used = 0
|
19
|
+
|
20
|
+
def getMemoryInfo(self):
|
21
|
+
self.__getMemory()
|
22
|
+
self.__memoryInfo.total = self.__mem_total / 1024 / 1024 # Convert bytes to MiB
|
23
|
+
self.__memoryInfo.used = self.__mem_used / 1024 / 1024 # Convert bytes to MiB
|
24
|
+
self.__memoryInfo.memory = f"{round(self.__memoryInfo.used, 2)} MiB / {round(self.__memoryInfo.total, 2)} MiB"
|
25
|
+
return self.__memoryInfo
|
26
|
+
|
27
|
+
def __getMemory(self):
|
28
|
+
self.__hw_pagesize = sysctlGetInt("hw.pagesize")
|
29
|
+
self.__mem_total = sysctlGetInt("hw.memsize")
|
30
|
+
self.__getVMStat()
|
31
|
+
self.__mem_used = self.__hw_pagesize * (self.__active_count + self.__inactive_count + self.__speculative_count +
|
32
|
+
self.__wire_count + self.__compressor_page_count -
|
33
|
+
self.__purgeable_count - self.__external_page_count)
|
34
|
+
|
35
|
+
def __getVMStat(self):
|
36
|
+
try:
|
37
|
+
result = subprocess.run(["vm_stat"], capture_output=True, text=True)
|
38
|
+
vm_stats = result.stdout.split("\n")
|
39
|
+
except subprocess.SubprocessError:
|
40
|
+
vm_stats = []
|
41
|
+
for vm_stat in vm_stats:
|
42
|
+
if vm_stat.startswith("Pages active"):
|
43
|
+
self.__active_count = int(vm_stat.split(":")[1].strip().split(".")[0])
|
44
|
+
elif vm_stat.startswith("Pages inactive"):
|
45
|
+
self.__inactive_count = int(vm_stat.split(":")[1].strip().split(".")[0])
|
46
|
+
elif vm_stat.startswith("Pages speculative"):
|
47
|
+
self.__speculative_count = int(vm_stat.split(":")[1].strip().split(".")[0])
|
48
|
+
elif vm_stat.startswith("Pages wired down"):
|
49
|
+
self.__wire_count = int(vm_stat.split(":")[1].strip().split(".")[0])
|
50
|
+
elif vm_stat.startswith("Pages occupied by compressor"): # compressor_page_count
|
51
|
+
self.__compressor_page_count = int(vm_stat.split(":")[1].strip().split(".")[0])
|
52
|
+
elif vm_stat.startswith("Pages purgeable"):
|
53
|
+
self.__purgeable_count = int(vm_stat.split(":")[1].strip().split(".")[0])
|
54
|
+
# miss external_page_count here
|
55
|
+
elif vm_stat.startswith("File-backed pages:"):
|
56
|
+
self.__external_page_count = int(vm_stat.split(":")[1].strip().split(".")[0])
|
@@ -1,4 +1,5 @@
|
|
1
1
|
from .linux import MemoryDetectLinux
|
2
|
+
from .macos import MemoryDetectMacOS
|
2
3
|
|
3
4
|
|
4
5
|
class MemoryDetect:
|
@@ -8,5 +9,7 @@ class MemoryDetect:
|
|
8
9
|
def getMemoryInfo(self):
|
9
10
|
if self.OS == "linux":
|
10
11
|
return MemoryDetectLinux().getMemoryInfo()
|
12
|
+
elif self.OS == "macos":
|
13
|
+
return MemoryDetectMacOS().getMemoryInfo()
|
11
14
|
else:
|
12
15
|
raise NotImplementedError("Unsupported operating system")
|
pyhw/backend/os/linux.py
CHANGED
@@ -1,27 +1,12 @@
|
|
1
1
|
"""
|
2
2
|
In dev.
|
3
3
|
"""
|
4
|
-
from
|
5
|
-
|
6
|
-
|
7
|
-
@dataclass
|
8
|
-
class OSInfoLinux:
|
9
|
-
prettyName = ""
|
10
|
-
name = ""
|
11
|
-
id = ""
|
12
|
-
idLike = ""
|
13
|
-
variant = ""
|
14
|
-
variantID = ""
|
15
|
-
version = ""
|
16
|
-
versionID = ""
|
17
|
-
versionCodename = ""
|
18
|
-
codeName = ""
|
19
|
-
buildID = ""
|
4
|
+
from .osInfo import OSInfo
|
20
5
|
|
21
6
|
|
22
7
|
class OSDetectLinux:
|
23
8
|
def __init__(self):
|
24
|
-
self.__osInfo =
|
9
|
+
self.__osInfo = OSInfo()
|
25
10
|
|
26
11
|
def getOSInfo(self):
|
27
12
|
"""
|
pyhw/backend/os/macos.py
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
from .osInfo import OSInfo
|
2
|
+
from ...pyhwUtil import getArch
|
3
|
+
import subprocess
|
4
|
+
|
5
|
+
|
6
|
+
class OSDetectMacOS:
|
7
|
+
def __init__(self):
|
8
|
+
self.__osInfo = OSInfo()
|
9
|
+
self.__ProductName = ""
|
10
|
+
self.__ProductVersion = ""
|
11
|
+
self.__BuildVersion = ""
|
12
|
+
self.__VersionName = ""
|
13
|
+
|
14
|
+
def getOSInfo(self):
|
15
|
+
self.__getOS()
|
16
|
+
self.__osInfo.prettyName = f"{self.__ProductName} {self.__ProductVersion} {self.__BuildVersion} {getArch()}"
|
17
|
+
self.__osInfo.id = "macOS"
|
18
|
+
return self.__osInfo
|
19
|
+
|
20
|
+
def __getOS(self):
|
21
|
+
try:
|
22
|
+
result = subprocess.run(["sw_vers"], capture_output=True, text=True)
|
23
|
+
sw_vers = result.stdout.split("\n")
|
24
|
+
except subprocess.SubprocessError:
|
25
|
+
sw_vers = []
|
26
|
+
for sw_ver in sw_vers:
|
27
|
+
if sw_ver.startswith("ProductName:"):
|
28
|
+
self.__ProductName = sw_ver.split(":")[1].strip()
|
29
|
+
elif sw_ver.startswith("ProductVersion:"):
|
30
|
+
self.__ProductVersion = sw_ver.split(":")[1].strip()
|
31
|
+
elif sw_ver.startswith("BuildVersion:"):
|
32
|
+
self.__BuildVersion = sw_ver.split(":")[1].strip()
|
33
|
+
|
34
|
+
def __handelOSName(self):
|
35
|
+
# Add os name -- product version conversion logic in the future.
|
36
|
+
pass
|
pyhw/backend/os/osBase.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
from .linux import OSDetectLinux
|
2
|
+
from .macos import OSDetectMacOS
|
2
3
|
from ...pyhwException import OSUnsupportedException
|
3
4
|
|
4
5
|
|
@@ -9,5 +10,7 @@ class OSDetect:
|
|
9
10
|
def getOSInfo(self):
|
10
11
|
if self.__OS == "linux":
|
11
12
|
return OSDetectLinux().getOSInfo()
|
13
|
+
elif self.__OS == "macos":
|
14
|
+
return OSDetectMacOS().getOSInfo()
|
12
15
|
else:
|
13
16
|
raise OSUnsupportedException("Unsupported operating system")
|
@@ -0,0 +1,17 @@
|
|
1
|
+
from dataclasses import dataclass
|
2
|
+
|
3
|
+
|
4
|
+
@dataclass
|
5
|
+
class OSInfo:
|
6
|
+
def __init__(self):
|
7
|
+
self.prettyName = ""
|
8
|
+
self.name = ""
|
9
|
+
self.id = ""
|
10
|
+
self.idLike = ""
|
11
|
+
self.variant = ""
|
12
|
+
self.variantID = ""
|
13
|
+
self.version = ""
|
14
|
+
self.versionID = ""
|
15
|
+
self.versionCodename = ""
|
16
|
+
self.codeName = ""
|
17
|
+
self.buildID = ""
|
pyhw/backend/uptime/linux.py
CHANGED
@@ -1,17 +1,12 @@
|
|
1
1
|
"""
|
2
2
|
In dev.
|
3
3
|
"""
|
4
|
-
from
|
5
|
-
|
6
|
-
|
7
|
-
@dataclass
|
8
|
-
class UptimeInfoLinux:
|
9
|
-
uptime = ""
|
4
|
+
from .uptimeInfo import UptimeInfo
|
10
5
|
|
11
6
|
|
12
7
|
class UptimeDetectLinux:
|
13
8
|
def __init__(self):
|
14
|
-
self.__uptimeInfo =
|
9
|
+
self.__uptimeInfo = UptimeInfo()
|
15
10
|
|
16
11
|
def getUptimeInfo(self):
|
17
12
|
self.__getUptime()
|
@@ -29,8 +24,8 @@ class UptimeDetectLinux:
|
|
29
24
|
seconds = int(seconds)
|
30
25
|
if days == 0:
|
31
26
|
if hours == 0:
|
32
|
-
self.__uptimeInfo.uptime = f"{minutes}
|
27
|
+
self.__uptimeInfo.uptime = f"{minutes} min {seconds} sec"
|
33
28
|
else:
|
34
|
-
self.__uptimeInfo.uptime = f"{hours} hours {minutes}
|
29
|
+
self.__uptimeInfo.uptime = f"{hours} hours {minutes} min {seconds} sec"
|
35
30
|
else:
|
36
|
-
self.__uptimeInfo.uptime = f"{days} days {hours} hours {minutes}
|
31
|
+
self.__uptimeInfo.uptime = f"{days} days {hours} hours {minutes} min {seconds} sec"
|
@@ -0,0 +1,40 @@
|
|
1
|
+
from .uptimeInfo import UptimeInfo
|
2
|
+
from ...pyhwUtil import sysctlGetString
|
3
|
+
import re
|
4
|
+
import subprocess
|
5
|
+
|
6
|
+
|
7
|
+
class UptimeDetectMacOS:
|
8
|
+
def __init__(self):
|
9
|
+
self.__uptimeInfo = UptimeInfo()
|
10
|
+
self.__boot_time = 0
|
11
|
+
self.__now = 0
|
12
|
+
|
13
|
+
def getUptimeInfo(self):
|
14
|
+
self.__getUptime()
|
15
|
+
uptime_seconds = self.__now - self.__boot_time
|
16
|
+
hours, remainder = divmod(uptime_seconds, 3600)
|
17
|
+
minutes, seconds = divmod(remainder, 60)
|
18
|
+
days, hours = divmod(hours, 24)
|
19
|
+
days = int(days)
|
20
|
+
hours = int(hours)
|
21
|
+
minutes = int(minutes)
|
22
|
+
seconds = int(seconds)
|
23
|
+
if days == 0:
|
24
|
+
if hours == 0:
|
25
|
+
self.__uptimeInfo.uptime = f"{minutes} min {seconds} sec"
|
26
|
+
else:
|
27
|
+
self.__uptimeInfo.uptime = f"{hours} hours {minutes} min {seconds} sec"
|
28
|
+
else:
|
29
|
+
self.__uptimeInfo.uptime = f"{days} days {hours} hours {minutes} min {seconds} sec"
|
30
|
+
return self.__uptimeInfo
|
31
|
+
|
32
|
+
def __getUptime(self):
|
33
|
+
result = sysctlGetString("kern.boottime")
|
34
|
+
match = re.search(r'sec = (\d+),', result)
|
35
|
+
if match:
|
36
|
+
self.__boot_time = int(match.group(1))
|
37
|
+
else:
|
38
|
+
return
|
39
|
+
self.__now = int(subprocess.check_output(["date", "+%s"]).decode().strip())
|
40
|
+
|
@@ -1,4 +1,5 @@
|
|
1
1
|
from .linux import UptimeDetectLinux
|
2
|
+
from .macos import UptimeDetectMacOS
|
2
3
|
from ...pyhwException import OSUnsupportedException
|
3
4
|
|
4
5
|
|
@@ -16,5 +17,7 @@ class UptimeDetect:
|
|
16
17
|
"""
|
17
18
|
if self.OS == "linux":
|
18
19
|
return UptimeDetectLinux().getUptimeInfo()
|
20
|
+
elif self.OS == "macos":
|
21
|
+
return UptimeDetectMacOS().getUptimeInfo()
|
19
22
|
else:
|
20
23
|
raise OSUnsupportedException("Unsupported operating system")
|
pyhw/frontend/frontendBase.py
CHANGED
@@ -57,7 +57,7 @@ class Printer:
|
|
57
57
|
def __DataPreprocess(self):
|
58
58
|
header_color = self.__config.get("colorTitle")
|
59
59
|
keys_color = self.__config.get("colorKeys")
|
60
|
-
self.__processed_data_lines.append("
|
60
|
+
self.__processed_data_lines.append(" " + colorPrefix(ColorSet.COLOR_MODE_BOLD) + colorPrefix(header_color) +
|
61
61
|
self.__data_lines[0].split("@")[0] + colorSuffix() + colorPrefix(ColorSet.COLOR_MODE_BOLD) +
|
62
62
|
"@" + colorPrefix(header_color) +
|
63
63
|
self.__data_lines[0].split("@")[1] + colorSuffix())
|
pyhw/pyhwUtil/__init__.py
CHANGED
@@ -1,3 +1,4 @@
|
|
1
1
|
from .pyhwUtil import getOS, getArch, createDataString, selectOSLogo
|
2
|
+
from .sysctlUtil import sysctlGetString, sysctlGetInt
|
2
3
|
|
3
|
-
__all__ = ["getOS", "getArch", "createDataString", "selectOSLogo"]
|
4
|
+
__all__ = ["getOS", "getArch", "createDataString", "selectOSLogo", "sysctlGetString", "sysctlGetInt"]
|
pyhw/pyhwUtil/pyhwUtil.py
CHANGED
@@ -2,10 +2,11 @@ import platform
|
|
2
2
|
from ..backend import Data
|
3
3
|
import os
|
4
4
|
|
5
|
+
|
5
6
|
def getOS():
|
6
7
|
"""
|
7
8
|
Get the os type in lower case.
|
8
|
-
:return: str, os type.
|
9
|
+
:return: str, os type, value in [windows, linux, macos, unknown].
|
9
10
|
"""
|
10
11
|
system = platform.system()
|
11
12
|
if system == "Windows":
|
@@ -17,6 +18,7 @@ def getOS():
|
|
17
18
|
else:
|
18
19
|
return "unknown"
|
19
20
|
|
21
|
+
|
20
22
|
def getArch():
|
21
23
|
"""
|
22
24
|
Get the machine architecture.
|
@@ -27,7 +29,7 @@ def getArch():
|
|
27
29
|
return "x86_64"
|
28
30
|
elif arch == "i386" or arch == "i686" or arch == "x86":
|
29
31
|
return "x86"
|
30
|
-
elif arch == "aarch64":
|
32
|
+
elif arch == "aarch64" or arch == "arm64":
|
31
33
|
return "aarch64"
|
32
34
|
elif arch.find("arm") != -1:
|
33
35
|
return "arm32"
|
@@ -36,18 +38,18 @@ def getArch():
|
|
36
38
|
|
37
39
|
|
38
40
|
def createDataString(data: Data):
|
39
|
-
data_string =
|
40
|
-
{data.title}
|
41
|
-
{
|
42
|
-
OS: {data.OS}
|
43
|
-
Host: {data.Host}
|
44
|
-
Kernel: {data.Kernel}
|
45
|
-
Uptime: {data.Uptime}
|
46
|
-
Shell: {data.Shell}
|
47
|
-
CPU: {data.CPU}
|
48
|
-
|
49
|
-
|
50
|
-
""
|
41
|
+
data_string = ""
|
42
|
+
data_string += f" {data.title}\n"
|
43
|
+
data_string += f" {'-'*len(data.title)}\n"
|
44
|
+
data_string += f" OS: {data.OS}\n"
|
45
|
+
data_string += f" Host: {data.Host}\n"
|
46
|
+
data_string += f" Kernel: {data.Kernel}\n"
|
47
|
+
data_string += f" Uptime: {data.Uptime}\n"
|
48
|
+
data_string += f" Shell: {data.Shell}\n"
|
49
|
+
data_string += f" CPU: {data.CPU}\n"
|
50
|
+
for gpu in data.GPU:
|
51
|
+
data_string += f" GPU: {gpu}\n"
|
52
|
+
data_string += f" Memory: {data.Memory}\n"
|
51
53
|
return data_string
|
52
54
|
|
53
55
|
|
@@ -57,6 +59,8 @@ def selectOSLogo(os_id: str):
|
|
57
59
|
:param os_id: str, os id.
|
58
60
|
:return: str, logo id.
|
59
61
|
"""
|
62
|
+
if getOS() == "macos":
|
63
|
+
return os_id
|
60
64
|
rows_str, columns_str = os.popen('stty size', 'r').read().split()
|
61
65
|
rows = int(rows_str)
|
62
66
|
columns = int(columns_str)
|
@@ -0,0 +1,37 @@
|
|
1
|
+
import subprocess
|
2
|
+
|
3
|
+
|
4
|
+
def __sysctlGet(key):
|
5
|
+
"""
|
6
|
+
Get value from sysctl by key.
|
7
|
+
:param key: str, sysctl key
|
8
|
+
:return: value of sysctl key or "" if not found
|
9
|
+
"""
|
10
|
+
try:
|
11
|
+
output = subprocess.run(["sysctl", "-n", key], capture_output=True, text=True).stdout.strip()
|
12
|
+
except subprocess.SubprocessError:
|
13
|
+
output = ""
|
14
|
+
return output
|
15
|
+
|
16
|
+
|
17
|
+
def sysctlGetString(key):
|
18
|
+
"""
|
19
|
+
Get value from sysctl by key.
|
20
|
+
:param key: str, sysctl key
|
21
|
+
:return: value of sysctl key or "" if not found
|
22
|
+
"""
|
23
|
+
return __sysctlGet(key)
|
24
|
+
|
25
|
+
|
26
|
+
def sysctlGetInt(key):
|
27
|
+
"""
|
28
|
+
Get value from sysctl by key.
|
29
|
+
:param key: str, sysctl key
|
30
|
+
:return: value of sysctl key as int or None if not found
|
31
|
+
"""
|
32
|
+
value = __sysctlGet(key)
|
33
|
+
try:
|
34
|
+
res = int(value)
|
35
|
+
except Exception:
|
36
|
+
res = None
|
37
|
+
return res
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: pyhw
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.2.0b0
|
4
4
|
Summary: PyHw, a neofetch-like command line tool for fetching system information but written mostly in python.
|
5
5
|
Author-email: Xiao Ran <xiaoran.007@icloud.com>
|
6
6
|
License: BSD-3-Clause
|
@@ -13,7 +13,12 @@ Description-Content-Type: text/markdown
|
|
13
13
|
License-File: LICENSE
|
14
14
|
|
15
15
|
# PyHw
|
16
|
-
|
16
|
+

|
17
|
+

|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
PyHw, a neofetch-like command line tool for fetching system information but written mostly in Python. **Currently, this project is still in the initial stage, only part of the linux systems and macOS are supported.**
|
17
22
|
|
18
23
|
This project is a Python reimplementation of [neofetch](https://github.com/dylanaraps/neofetch) and references the [fastfetch](https://github.com/fastfetch-cli/fastfetch) project for logo style settings. Since this project is implemented in Python, it will be easier to maintain and extend than bash and c implementation. Also, this project only relies on the Python standard library, so you can run it on any device that has a Python environment (I hope so 🤔)
|
19
24
|
|
@@ -1,31 +1,40 @@
|
|
1
1
|
pyhw/__init__.py,sha256=IMjkMO3twhQzluVTo8Z6rE7Eg-9U79_LGKMcsWLKBkY,22
|
2
|
-
pyhw/__main__.py,sha256=
|
2
|
+
pyhw/__main__.py,sha256=Ez3TaVt5NaTwEgDUnHzhUhyVMfrSDC2cSwv8AEmg8c4,1557
|
3
3
|
pyhw/macos.py,sha256=kF973QvtEFky4m8RnYTJ-HWPuJi3625tvnWqJAT_DHM,4598
|
4
4
|
pyhw/backend/__init__.py,sha256=knn_3Yroow1h0dqdrozk3zyy3vz-kQyNBRjR6OLmVoY,50
|
5
5
|
pyhw/backend/backendBase.py,sha256=t9FKQPdK7yFZF0vrsXpjIUJNKrB-cXYeL5MDohlgguA,450
|
6
6
|
pyhw/backend/cpu/__init__.py,sha256=5YfANJVRwNwTRodG0ENOgusrdN592aaSnfq5ok4dKTo,56
|
7
|
-
pyhw/backend/cpu/cpuBase.py,sha256=
|
8
|
-
pyhw/backend/cpu/
|
7
|
+
pyhw/backend/cpu/cpuBase.py,sha256=AGWqVjdvb82NiH4kxk3GERdBLwBNhkR23j2ei_l3S18,464
|
8
|
+
pyhw/backend/cpu/cpuInfo.py,sha256=A_nNGElq9W7oZ5DFJowLdFBE0ZvXKr5h29E6TGAvbRc,251
|
9
|
+
pyhw/backend/cpu/linux.py,sha256=J_oKa4BB_E5pBrMMuIORhNauXzPsyB2vsoJcUei9Ljg,2271
|
10
|
+
pyhw/backend/cpu/macos.py,sha256=mnnH9ABiBgAiyA8-H9_tq2PC5OeneVLj67nMGoLDXh4,2873
|
9
11
|
pyhw/backend/gpu/__init__.py,sha256=EpMjPvUaXt0LTNMvGmB8WgXbUB9keCxuOhu8NT3Re6o,56
|
10
|
-
pyhw/backend/gpu/gpuBase.py,sha256=
|
11
|
-
pyhw/backend/gpu/
|
12
|
+
pyhw/backend/gpu/gpuBase.py,sha256=Ge0DX2P8_EB7ovM7glmPUnVsPJL3OUHV2t_1T5mimR0,409
|
13
|
+
pyhw/backend/gpu/gpuInfo.py,sha256=d_z_z5DiZAg85wP0VOBQEU0QHdaK3qFqA2Tp9Eq8-Zs,133
|
14
|
+
pyhw/backend/gpu/linux.py,sha256=Tj7ngrSvVpBGtx3HxuSNcWEXbTeIea8ef5qL341JQYQ,1448
|
15
|
+
pyhw/backend/gpu/macos.py,sha256=sgrROfJC59KWjxfW2n90thVEjgDNYYLWo_pETDFPKQA,2308
|
12
16
|
pyhw/backend/host/__init__.py,sha256=Efaj7-Oya7H8HdpZHQCLrwn-mcfPb-d6yfh4dzsE_7I,58
|
13
|
-
pyhw/backend/host/hostBase.py,sha256=
|
14
|
-
pyhw/backend/host/
|
15
|
-
pyhw/backend/host/
|
17
|
+
pyhw/backend/host/hostBase.py,sha256=POyDW3f5JSWtEKyCfrVSBEddSwoywe_OBgUExCEuje8,563
|
18
|
+
pyhw/backend/host/hostInfo.py,sha256=Xvz0LugPiCSWMkcDsp4p2rrojYFZauL6Q-gCZ6NLz5k,184
|
19
|
+
pyhw/backend/host/linux.py,sha256=Ozl3tkDx-5OQ6mcocn4ap2KN7F8eE1JKB9g3qypHkxQ,1173
|
20
|
+
pyhw/backend/host/macos.py,sha256=u-Orwcq0FCcr2eR9mOKUc85LGkyuiO6rZ-ggIwob92k,14593
|
16
21
|
pyhw/backend/host/windows.py,sha256=rjDJaIs-5zspzFsNCMCh6m2yZXEXI0vccqeBpmAdEBk,53
|
17
22
|
pyhw/backend/kernel/__init__.py,sha256=fGjwjpOhwA_PnsWbwoq102hwhTay2ufYKaTqxjSV2-I,65
|
18
|
-
pyhw/backend/kernel/kernelBase.py,sha256=
|
19
|
-
pyhw/backend/kernel/
|
20
|
-
pyhw/backend/kernel/
|
23
|
+
pyhw/backend/kernel/kernelBase.py,sha256=CMvBszl4_aP48YWnFI03I2GtngYStkcY4uDU3ub8C3E,555
|
24
|
+
pyhw/backend/kernel/kernelInfo.py,sha256=QQYni0IVeFZ2IVNDC06U728Q01Rq3R6qRDYCxMjtJrY,189
|
25
|
+
pyhw/backend/kernel/unix.py,sha256=XDV2GIjamERcmlrQFaKFZY-OJO1xj76Im_7lmg2uFzo,1192
|
21
26
|
pyhw/backend/kernel/windows.py,sha256=lxZ7T9Ea0Qbq3pf_TjSAHSM2YTozC6ivv7dKdLOTl3s,58
|
22
27
|
pyhw/backend/memory/__init__.py,sha256=zGBWxfPAAk8ivCBWPLJIpuD-lB7wUJT3x8u2jHiAoCY,65
|
23
|
-
pyhw/backend/memory/linux.py,sha256=
|
24
|
-
pyhw/backend/memory/
|
28
|
+
pyhw/backend/memory/linux.py,sha256=eEH3oOYdbANw2B0Ce32fDOidh1GhtEd_UPIo2GohBEA,929
|
29
|
+
pyhw/backend/memory/macos.py,sha256=ur2HxmmmVkXmaxEcw_otphifVp_csfNMJdgt-idCq7M,2770
|
30
|
+
pyhw/backend/memory/memoryBase.py,sha256=RFRWTByH25T3T77maxLyIRRoedIi5M8XLtVbvwBmjfY,433
|
31
|
+
pyhw/backend/memory/memoryInfo.py,sha256=OQF165uEyuapAsi7cKacQYDRnKdrQHeldfyFwzS9N2g,186
|
25
32
|
pyhw/backend/metal/t.py,sha256=52yv-JoXNfaIOfcxEEidIg0MoyFtzWvTRm550kQKPZA,391
|
26
33
|
pyhw/backend/os/__init__.py,sha256=rPHQYdQK3qU6ZwwodqVoEWeqBnKffXlJyi4k3-8ViPY,53
|
27
|
-
pyhw/backend/os/linux.py,sha256=
|
28
|
-
pyhw/backend/os/
|
34
|
+
pyhw/backend/os/linux.py,sha256=fGVmJoKw65JdgWsJjbjAxOVqw0dqkmw-BQSb-TnSQQc,1782
|
35
|
+
pyhw/backend/os/macos.py,sha256=bJU8-Uan8yRdAYWroN6wJ1XQA3US-2ikBLWwbDJhBeg,1261
|
36
|
+
pyhw/backend/os/osBase.py,sha256=AA17HIwmWy7E6nCtqbojTNsHKtcNuehf51FxGcfXu7A,462
|
37
|
+
pyhw/backend/os/osInfo.py,sha256=iLPc7INFHH3izascwooj4JBVgvBsSgVPXWBlFXG47mQ,378
|
29
38
|
pyhw/backend/shell/__init__.py,sha256=SeQ7OLNSl_V1JCCWnJGjLilAWiSe9e5kgsMEt63TMS0,62
|
30
39
|
pyhw/backend/shell/shellBase.py,sha256=mylNazVtTbCSzus-IPe1QwnuIGSFNP-z5vYKwTIl_yg,377
|
31
40
|
pyhw/backend/shell/unix.py,sha256=COPpSE_wnuuSWDckTvBT0nNwLzgh8iPLicY8XghTSYM,1530
|
@@ -34,10 +43,12 @@ pyhw/backend/title/titleBase.py,sha256=pcnkiNn9N69yc4iicAmpMpC6G7HUMyGCh0V1jjGIP
|
|
34
43
|
pyhw/backend/title/unix.py,sha256=9B-zLE8yhlWBnJ-6Aa-DmFmgMV9KdvvNU40drJIaNck,837
|
35
44
|
pyhw/backend/title/windows.py,sha256=5bXR6yxHk3diVx92sjxPeD6fUVR5sKZJG3K4aM3CGn8,82
|
36
45
|
pyhw/backend/uptime/__init__.py,sha256=X8RVhHWmHpyey0C4gcmrt_u1cHKowhAQRDMAxY3i7p0,65
|
37
|
-
pyhw/backend/uptime/linux.py,sha256=
|
38
|
-
pyhw/backend/uptime/
|
46
|
+
pyhw/backend/uptime/linux.py,sha256=Sh05CgUjAOzPM8LSoZf4fCU-Cl5pwhSJSC7XJ-jFaHU,1027
|
47
|
+
pyhw/backend/uptime/macos.py,sha256=8lTlR0WUzgGqUNspqegg4dP_j5ySOCTyFlXpyRBJ-Jw,1306
|
48
|
+
pyhw/backend/uptime/uptimeBase.py,sha256=cP6aTPnFe6XQHgBX7YcDuuGHARI11ctMlyrrtsU-Opc,657
|
49
|
+
pyhw/backend/uptime/uptimeInfo.py,sha256=TobPEV3MBT3Fiv3W6TOzD3a4MNW-vz2Oi_Trlcihu7k,114
|
39
50
|
pyhw/frontend/__init__.py,sha256=xgv_iVv9w4cLXklbdtFWXu7J7KJxBCUw-ZcUQb_abFc,57
|
40
|
-
pyhw/frontend/frontendBase.py,sha256=
|
51
|
+
pyhw/frontend/frontendBase.py,sha256=VjZ-_sV-awDJVLHBzG8z3YK3W92-SS_Q5-_Q0PgyB3w,3708
|
41
52
|
pyhw/frontend/color/__init__.py,sha256=xk511qWwdYWEVjk_zOaC4fs81HtwR4ELr3wi1tTL824,191
|
42
53
|
pyhw/frontend/color/colorConfig.py,sha256=jPjLzv67haEr6rNC2hoNLJLWHO5LQx4zBbLTy3FHA0E,2718
|
43
54
|
pyhw/frontend/color/colorSet.py,sha256=spH8PlRu7capouf-yUgDHgoPCnM5aJ_ncascISZfz2g,1421
|
@@ -53,11 +64,12 @@ pyhw/frontend/logo/ascii/ubuntu.pyhw,sha256=l-Q0PfutxXYMwTojqeiM88063x4V0RBkZUHm
|
|
53
64
|
pyhw/frontend/logo/ascii/ubuntu_small.pyhw,sha256=Xf8LSZdZUu9aEG3efhb1FUlUEuJ-3UztcIOJISpKhPw,229
|
54
65
|
pyhw/pyhwException/__init__.py,sha256=8JsFvtF13g0Y5t4z9fRndDXtfCzuBM59jDf6PhWSFSk,220
|
55
66
|
pyhw/pyhwException/pyhwException.py,sha256=wxuzFQa9g7XB1q9TUKO_55lw7wMEJMpzG8w1GVTFVa0,197
|
56
|
-
pyhw/pyhwUtil/__init__.py,sha256=
|
57
|
-
pyhw/pyhwUtil/pyhwUtil.py,sha256=
|
58
|
-
pyhw
|
59
|
-
pyhw-0.
|
60
|
-
pyhw-0.
|
61
|
-
pyhw-0.
|
62
|
-
pyhw-0.
|
63
|
-
pyhw-0.
|
67
|
+
pyhw/pyhwUtil/__init__.py,sha256=PzeP9fXsIhvr3sUpJ4DxW9_H25DEIasBFfXd_NztfR4,226
|
68
|
+
pyhw/pyhwUtil/pyhwUtil.py,sha256=Y_i_LUAAtQ8pLTna0mThzEh6ekrDfQ5JZ44Rtp2jSx4,1944
|
69
|
+
pyhw/pyhwUtil/sysctlUtil.py,sha256=S-rUvqi7ZrMyMouIhxlyHEQ4agM7sCT1Y7uzs3Hu5-o,841
|
70
|
+
pyhw-0.2.0b0.dist-info/LICENSE,sha256=hJs6RBqSVCexbTsalkMLNFI5t06kekQEsSVaOt_-yLs,1497
|
71
|
+
pyhw-0.2.0b0.dist-info/METADATA,sha256=gmaNKWAc2PSWue_I__lz1BsVa7nMLSkz3O2ADqt62Tg,2084
|
72
|
+
pyhw-0.2.0b0.dist-info/WHEEL,sha256=HiCZjzuy6Dw0hdX5R3LCFPDmFS4BWl8H-8W39XfmgX4,91
|
73
|
+
pyhw-0.2.0b0.dist-info/entry_points.txt,sha256=q-AB8im_QahpmNrmy4aPTJRGi0LlbNlnI3kF7s6pKss,44
|
74
|
+
pyhw-0.2.0b0.dist-info/top_level.txt,sha256=7Inxvxt1TngEricKZEex9_WJZS3DbKYFUXDz4v5WHYU,5
|
75
|
+
pyhw-0.2.0b0.dist-info/RECORD,,
|
pyhw/backend/kernel/macos.py
DELETED
File without changes
|
File without changes
|
File without changes
|
File without changes
|