pyhw 0.1.2b0__py3-none-any.whl → 0.2.0b0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyhw/__main__.py +16 -14
- pyhw/backend/cpu/cpuBase.py +3 -0
- pyhw/backend/cpu/cpuInfo.py +13 -0
- pyhw/backend/cpu/linux.py +8 -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.2b0.dist-info → pyhw-0.2.0b0.dist-info}/METADATA +7 -4
- {pyhw-0.1.2b0.dist-info → pyhw-0.2.0b0.dist-info}/RECORD +38 -26
- pyhw/backend/kernel/macos.py +0 -7
- {pyhw-0.1.2b0.dist-info → pyhw-0.2.0b0.dist-info}/LICENSE +0 -0
- {pyhw-0.1.2b0.dist-info → pyhw-0.2.0b0.dist-info}/WHEEL +0 -0
- {pyhw-0.1.2b0.dist-info → pyhw-0.2.0b0.dist-info}/entry_points.txt +0 -0
- {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 | 
            -
                 | 
| 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,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 =  | 
| 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( | 
| 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")
         | 
    
        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,9 +1,7 @@ | |
| 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 | 
            -
            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 | 
            -
             | 
| 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.**
         | 
| 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= | 
| 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
         |