pyhw 0.1.2b0__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.
Files changed (39) hide show
  1. pyhw/__main__.py +16 -14
  2. pyhw/backend/cpu/cpuBase.py +3 -0
  3. pyhw/backend/cpu/cpuInfo.py +13 -0
  4. pyhw/backend/cpu/linux.py +8 -11
  5. pyhw/backend/cpu/macos.py +69 -0
  6. pyhw/backend/gpu/gpuBase.py +3 -0
  7. pyhw/backend/gpu/gpuInfo.py +8 -0
  8. pyhw/backend/gpu/linux.py +3 -9
  9. pyhw/backend/gpu/macos.py +63 -0
  10. pyhw/backend/host/hostBase.py +1 -1
  11. pyhw/backend/host/hostInfo.py +13 -0
  12. pyhw/backend/host/linux.py +2 -14
  13. pyhw/backend/host/macos.py +265 -1
  14. pyhw/backend/kernel/kernelBase.py +4 -4
  15. pyhw/backend/kernel/kernelInfo.py +10 -0
  16. pyhw/backend/kernel/{linux.py → unix.py} +3 -14
  17. pyhw/backend/memory/linux.py +2 -10
  18. pyhw/backend/memory/macos.py +56 -0
  19. pyhw/backend/memory/memoryBase.py +3 -0
  20. pyhw/backend/memory/memoryInfo.py +10 -0
  21. pyhw/backend/os/linux.py +2 -17
  22. pyhw/backend/os/macos.py +36 -0
  23. pyhw/backend/os/osBase.py +3 -0
  24. pyhw/backend/os/osInfo.py +17 -0
  25. pyhw/backend/uptime/linux.py +5 -10
  26. pyhw/backend/uptime/macos.py +40 -0
  27. pyhw/backend/uptime/uptimeBase.py +3 -0
  28. pyhw/backend/uptime/uptimeInfo.py +7 -0
  29. pyhw/frontend/frontendBase.py +1 -1
  30. pyhw/pyhwUtil/__init__.py +2 -1
  31. pyhw/pyhwUtil/pyhwUtil.py +18 -14
  32. pyhw/pyhwUtil/sysctlUtil.py +37 -0
  33. {pyhw-0.1.2b0.dist-info → pyhw-0.2.0b0.dist-info}/METADATA +7 -4
  34. {pyhw-0.1.2b0.dist-info → pyhw-0.2.0b0.dist-info}/RECORD +38 -26
  35. pyhw/backend/kernel/macos.py +0 -7
  36. {pyhw-0.1.2b0.dist-info → pyhw-0.2.0b0.dist-info}/LICENSE +0 -0
  37. {pyhw-0.1.2b0.dist-info → pyhw-0.2.0b0.dist-info}/WHEEL +0 -0
  38. {pyhw-0.1.2b0.dist-info → pyhw-0.2.0b0.dist-info}/entry_points.txt +0 -0
  39. {pyhw-0.1.2b0.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
- print("This is a test version of PyHw. Currently, it only supports Linux.")
18
- if getOS() != "linux":
19
- print(f"Only Linux is supported for now. Current os: {getOS()}")
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="linux").getTitle().title
23
- data.Host = HostDetect(os="linux").getHostInfo().model
24
- data.Kernel = KernelDetect(os="linux").getKernelInfo().kernel
25
- data.Shell = ShellDetect(os="linux").getShellInfo().info
26
- data.Uptime = UptimeDetect(os="linux").getUptime().uptime
27
- data.OS = OSDetect(os="linux").getOSInfo().prettyName
28
- data.CPU = CPUDetect(os="linux").getCPUInfo().cpu
29
- if GPUDetect(os="linux").getGPUInfo().number > 0:
30
- data.GPU = GPUDetect(os="linux").getGPUInfo().gpus
31
- data.Memory = MemoryDetect(os="linux").getMemoryInfo().memory
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="linux").getOSInfo().id), data=createDataString(data)).cPrint()
35
+ Printer(logo_os=selectOSLogo(OSDetect(os=current_os).getOSInfo().id), data=createDataString(data)).cPrint()
34
36
 
35
37
 
36
38
  if __name__ == "__main__":
@@ -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")
@@ -0,0 +1,13 @@
1
+ from dataclasses import dataclass
2
+
3
+
4
+ @dataclass
5
+ class CPUInfo:
6
+ """
7
+ Class to store CPU information. Print key: cpu
8
+ """
9
+ def __init__(self):
10
+ self.cpu = ""
11
+ self.model = ""
12
+ self.cores = ""
13
+ self.frequency = ""
pyhw/backend/cpu/linux.py CHANGED
@@ -1,22 +1,15 @@
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 = CPUInfoLinux()
8
+ self.__cpuInfo = CPUInfo()
17
9
 
18
10
  def getCPUInfo(self):
19
11
  self.__getCPUInfo()
12
+ self.__modelClean()
20
13
  if self.__cpuInfo.model != "":
21
14
  self.__cpuInfo.cpu = self.__cpuInfo.model
22
15
  if self.__cpuInfo.cores != "":
@@ -52,5 +45,9 @@ class CPUDetectLinux:
52
45
  else:
53
46
  for line in cpu_info.split("\n"):
54
47
  if line.startswith("cpu MHz") or line.startswith("clock"):
55
- self.__cpuInfo.frequency = float(line.split(":")[1].strip()) / 1000 # Ghz
48
+ self.__cpuInfo.frequency = f"{round(float(line.split(':')[1].strip()) / 1000, 2)} Ghz" # Ghz
56
49
  break
50
+
51
+ def __modelClean(self):
52
+ self.__cpuInfo.model = self.__cpuInfo.model.replace("(R)", "")
53
+ self.__cpuInfo.model = self.__cpuInfo.model.replace("(TM)", "")
@@ -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")
@@ -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")
@@ -0,0 +1,8 @@
1
+ from dataclasses import dataclass
2
+
3
+
4
+ @dataclass
5
+ class GPUInfo:
6
+ def __init__(self):
7
+ self.number = 0
8
+ self.gpus = []
pyhw/backend/gpu/linux.py CHANGED
@@ -1,18 +1,12 @@
1
1
  import subprocess
2
- from dataclasses import dataclass
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 = GPUInfoLinux()
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} (SOC Integrated Graphics)")
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
@@ -12,7 +12,7 @@ class HostDetect:
12
12
  if self.OS == "linux":
13
13
  return HostDetectLinux().getHostInfo()
14
14
  elif self.OS == "macos":
15
- pass
15
+ return HostDetectMacOS().getHostInfo()
16
16
  elif self.OS == "windows":
17
17
  pass
18
18
  else:
@@ -0,0 +1,13 @@
1
+ from dataclasses import dataclass
2
+
3
+
4
+ @dataclass
5
+ class HostInfo:
6
+ model = ""
7
+ family = ""
8
+ name = ""
9
+ version = ""
10
+ sku = ""
11
+ serial = ""
12
+ uuid = ""
13
+ vendor = ""
@@ -2,24 +2,12 @@
2
2
  In dev.
3
3
  """
4
4
  from ...pyhwUtil import getArch
5
- from dataclasses import dataclass
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 = HostInfoLinux()
10
+ self.__hostInfo = HostInfo()
23
11
  self.__arch = getArch()
24
12
 
25
13
  def getHostInfo(self):
@@ -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
- pass
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 .linux import KernelDetectLinux
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 KernelDetectLinux().getKernelInfo()
11
+ return KernelDetectUnix().getKernelInfo()
12
12
  elif self.OS == "macos":
13
- pass
13
+ return KernelDetectUnix().getKernelInfo()
14
14
  elif self.OS == "windows":
15
- pass
15
+ raise OSUnsupportedException("Unsupported operating system")
16
16
  else:
17
17
  raise OSUnsupportedException("Unsupported operating system")
@@ -0,0 +1,10 @@
1
+ from dataclasses import dataclass
2
+
3
+
4
+ @dataclass
5
+ class KernelInfo:
6
+ def __init__(self):
7
+ self.name = ""
8
+ self.version = ""
9
+ self.machine = ""
10
+ self.kernel = ""
@@ -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
- @dataclass
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 = KernelInfoLinux()
7
+ self.__kernelInfo = KernelInfo()
19
8
 
20
9
  def getKernelInfo(self):
21
10
  self.__getKernelName()
@@ -1,17 +1,9 @@
1
- from dataclasses import dataclass
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 = MemoryInfoLinux()
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")
@@ -0,0 +1,10 @@
1
+ from dataclasses import dataclass
2
+
3
+
4
+ @dataclass
5
+ class MemoryInfo:
6
+ def __init__(self):
7
+ self.memory = ""
8
+ self.total = 0
9
+ self.available = 0
10
+ self.used = 0
pyhw/backend/os/linux.py CHANGED
@@ -1,27 +1,12 @@
1
1
  """
2
2
  In dev.
3
3
  """
4
- from dataclasses import dataclass
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 = OSInfoLinux()
9
+ self.__osInfo = OSInfo()
25
10
 
26
11
  def getOSInfo(self):
27
12
  """
@@ -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 = ""
@@ -1,17 +1,12 @@
1
1
  """
2
2
  In dev.
3
3
  """
4
- from dataclasses import dataclass
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 = UptimeInfoLinux()
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} minutes {seconds} seconds"
27
+ self.__uptimeInfo.uptime = f"{minutes} min {seconds} sec"
33
28
  else:
34
- self.__uptimeInfo.uptime = f"{hours} hours {minutes} minutes {seconds} seconds"
29
+ self.__uptimeInfo.uptime = f"{hours} hours {minutes} min {seconds} sec"
35
30
  else:
36
- self.__uptimeInfo.uptime = f"{days} days {hours} hours {minutes} minutes {seconds} seconds"
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")
@@ -0,0 +1,7 @@
1
+ from dataclasses import dataclass
2
+
3
+
4
+ @dataclass
5
+ class UptimeInfo:
6
+ def __init__(self):
7
+ self.uptime = ""
@@ -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(" " + colorPrefix(ColorSet.COLOR_MODE_BOLD) + colorPrefix(header_color) +
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 = f"""
40
- {data.title}
41
- {"-"*len(data.title)}
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
- GPU: {data.GPU[0]}
49
- Memory: {data.Memory}
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,9 +1,7 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyhw
3
- Version: 0.1.2b0
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
- Home-page: https://github.com/xiaoran007/pyhw
6
- Author: Xiao Ran
7
5
  Author-email: Xiao Ran <xiaoran.007@icloud.com>
8
6
  License: BSD-3-Clause
9
7
  Project-URL: homepage, https://github.com/xiaoran007/pyhw
@@ -15,7 +13,12 @@ Description-Content-Type: text/markdown
15
13
  License-File: LICENSE
16
14
 
17
15
  # PyHw
18
- 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 are supported. macOS support will be added soon.
16
+ ![PyPI - Downloads](https://img.shields.io/pypi/dw/pyhw?label=PyPI)
17
+ ![PyPI - Version](https://img.shields.io/pypi/v/pyhw?label=version)
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.**
19
22
 
20
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 🤔)
21
24
 
@@ -1,31 +1,40 @@
1
1
  pyhw/__init__.py,sha256=IMjkMO3twhQzluVTo8Z6rE7Eg-9U79_LGKMcsWLKBkY,22
2
- pyhw/__main__.py,sha256=HH17lyJ0KJVmlES4pOanM-hWcK1qi03Cwb-s0jxT3PA,1452
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=VwVq7uazw90N02Sdvk1XK-K0MKgDA_FYDsLyWAxBzkc,348
8
- pyhw/backend/cpu/linux.py,sha256=hZhwr9ZtcWHd4zmrjZWxob7gBNeQ-rNnjkV7X-0sS-U,2157
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=tTl9L0CKc49VkaEYGFEp_8A5Mmzfpd9h3DaKN0-FwFA,293
11
- pyhw/backend/gpu/linux.py,sha256=Ds0V7SZ-lhY4ZG2R6tGfcNJASHKXZfzIHJFgYYyvSMg,1529
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=Pb4lHiXLYWe2pBL5PqYPubsTPhtIMCcdSa_Fvp5lybg,529
14
- pyhw/backend/host/linux.py,sha256=-iHCxqd54OKekBpADJFzR4Rusx3C781s5LGDIbjByAc,1336
15
- pyhw/backend/host/macos.py,sha256=imErUWZhyX8vfYYgSOBspXh-y0rQeZgyKIIawLa6ZEE,51
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=qroX2ekvZ3DmKCAYwDujGUef-CMG53joHLdGMZMLNUY,465
19
- pyhw/backend/kernel/linux.py,sha256=QRJrJ89O3U29MurxqhcnfPseH1V-L1Rz1xC0XwEdkRI,1317
20
- pyhw/backend/kernel/macos.py,sha256=SVa2FolhWLH9Lf6lL4nEM5w1UZlmYeMEAgc8-EgiKzw,56
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=9-h3kaRjTNDlNBZv5sUJn_I_drw8lgQRHsimV_CO8zU,1030
24
- pyhw/backend/memory/memoryBase.py,sha256=AfqRw6dBw87M-MUVmD2fD-XGWFxXm64gnaOMd1NjzeI,308
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=ERDrZnvUiS0c3VSdlDje054aEcbtCeuIC4QsoTi6koM,2020
28
- pyhw/backend/os/osBase.py,sha256=3phvYUBcsOfv9_0ChkLIYAVp6nMLSZ40_Aop4T-emlg,347
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=k4sruxxkC0GW5gHSiMdwraP7KPb-KasinAiqHXddZIU,1107
38
- pyhw/backend/uptime/uptimeBase.py,sha256=_sloK7fKJB3qwKT-1jBJXJPkKB-eBDKqkn4ZbEvnru8,532
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=I3jSBeoVAp22XEiK1qOkVLN3Okx-kroU0Rn7fO7bVkw,3711
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=T87U8jEL-Z0jBZOYAzZpqu_8jBYRkqIONG6ZCARl8nc,137
57
- pyhw/pyhwUtil/pyhwUtil.py,sha256=MNAePrn17jNugorg8WLPhl_aFjfQxEpJQ8pBWLhd9gA,1611
58
- pyhw-0.1.2b0.dist-info/LICENSE,sha256=hJs6RBqSVCexbTsalkMLNFI5t06kekQEsSVaOt_-yLs,1497
59
- pyhw-0.1.2b0.dist-info/METADATA,sha256=XODZ4iRBefEfj47us4NDEPSXZX3HKmk1_8b7mHJmCEQ,2028
60
- pyhw-0.1.2b0.dist-info/WHEEL,sha256=HiCZjzuy6Dw0hdX5R3LCFPDmFS4BWl8H-8W39XfmgX4,91
61
- pyhw-0.1.2b0.dist-info/entry_points.txt,sha256=q-AB8im_QahpmNrmy4aPTJRGi0LlbNlnI3kF7s6pKss,44
62
- pyhw-0.1.2b0.dist-info/top_level.txt,sha256=7Inxvxt1TngEricKZEex9_WJZS3DbKYFUXDz4v5WHYU,5
63
- pyhw-0.1.2b0.dist-info/RECORD,,
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,,
@@ -1,7 +0,0 @@
1
- """
2
- In dev.
3
- """
4
-
5
-
6
- class KernelDetectMacOS:
7
- pass
File without changes