Исходный код EJIO.utils.system.hardware

## /utils/system/hardware.py

from typing import Any
from ..interface import ReadOnlyMeta
from .properties import SystemProperties

__all__ = [
    'HardwareProperties',
]


[документация] class HardwareProperties(metaclass=ReadOnlyMeta): """ Неизменяемая структура рантайм-сведений об аппаратном обеспечении (Железе). Полностью кроссплатформенна, работает через Си-вызовы и парсинг системных утилит. """ __slots__ = () @staticmethod def cpu_model() -> str: """Возвращает коммерческое наименование процессора.""" sys_name = SystemProperties.os try: if sys_name == "windows": import subprocess out = subprocess.check_output("wmic cpu get name", shell=True, text=True) return out.splitlines()[2].strip() elif sys_name == "darwin": import subprocess return subprocess.check_output(["sysctl", "-n", "machdep.cpu.brand_string"], text=True).strip() else: # Linux with open("/proc/cpuinfo", "r") as f: for line in f: if "model name" in line: return line.split(":")[1].strip() except Exception: pass return "Unknown Processor" @staticmethod def cpu_cores() -> int: """Возвращает общее количество логических ядер.""" try: import os return os.cpu_count() or 1 except Exception: return 1 @staticmethod def ram_total_gb() -> int: """Возвращает общий объем оперативной памяти в гигабайтах (округленный).""" sys_name = SystemProperties.os try: if sys_name == "windows": import subprocess out = subprocess.check_output("wmic computersystem get totalphysicalmemory", shell=True, text=True) bytes_ram = int(out.splitlines()[2].strip()) return round(bytes_ram / (1024 ** 3)) elif sys_name == "darwin": import subprocess bytes_ram = int(subprocess.check_output(["sysctl", "-n", "hw.memsize"], text=True).strip()) return round(bytes_ram / (1024 ** 3)) else: # Linux with open("/proc/meminfo", "r") as f: for line in f: if "MemTotal" in line: kb_ram = int(re.search(r"\d+", line).group()) # type: ignore return round(kb_ram / (1024 ** 2)) except Exception: pass return 8 @staticmethod def gpu_model() -> str: """Возвращает наименование активной дискретной или встроенной видеокарты.""" sys_name = SystemProperties.os try: if sys_name == "windows": import subprocess out = subprocess.check_output("wmic path win32_VideoController get name", shell=True, text=True) return out.splitlines()[2].strip() elif sys_name == "darwin": import subprocess out = subprocess.check_output("system_profiler SPDisplaysDataType | grep 'Chipset Model'", shell=True, text=True) return out.split(":")[1].strip() else: # Linux import subprocess import re out = subprocess.check_output("lspci | grep -E 'VGA|3D'", shell=True, text=True) match = re.search(r"controller:\s+(.+)", out, re.IGNORECASE) return match.group(1).strip() if match else out.strip() except Exception: pass return "Integrated Graphics Controller" @staticmethod def motherboard() -> str: """Возвращает модель материнской платы (или платы системного контура).""" sys_name = SystemProperties.os try: if sys_name == "windows": import subprocess out_m = subprocess.check_output("wmic baseboard get product", shell=True, text=True) out_v = subprocess.check_output("wmic baseboard get manufacturer", shell=True, text=True) return f"{out_v.splitlines()[2].strip()} {out_m.splitlines()[2].strip()}" elif sys_name == "darwin": return "Apple Motherboard (Logic Board)" else: # Linux with open("/sys/class/dmi/id/board_name", "r") as f: m = f.read().strip() with open("/sys/class/dmi/id/board_vendor", "r") as f: v = f.read().strip() return f"{v} {m}" except Exception: pass return "Baseboard Mainboard" @staticmethod def storage_drives() -> list[dict[str, Any]]: """ Возвращает структурированный список всех физических дисков в системе с указанием их типа (SSD/HDD), буквы/имени и объема в ГБ. """ sys_name = SystemProperties.os drives: list[dict[str, Any]] = [] try: if sys_name == "windows": import subprocess import json # Ультимативный PowerShell скрипт. Он берет каждую букву диска, находит ее физический # индекс Win32_DiskDrive и запрашиваетMediaType из хранилища. ЕслиMediaType скрыт (Unspecified), # он проверяет флаг вращения или паспортные характеристики устройства. ps_script = ( "Get-CimInstance Win32_LogicalDisk | Where-Object { $_.DriveType -eq 3 } | ForEach-Object { " "$letter = $_.DeviceID; " "$sizeGb = [Math]::Round($_.Size / 1Gb); " "$partition = Get-CimAssociator -Instance $_ -AssocClassName Win32_LogicalDiskToPartition; " "$drive = Get-CimAssociator -Instance $partition -AssocClassName Win32_DiskDriveToDiskPartition; " "$phys = Get-CimInstance -Namespace root/Microsoft/Windows/Storage -ClassName MSFT_PhysicalDisk | " "Where-Object { $_.DeviceId -eq $drive.Index }; " "$type = 'HDD'; " "if ($phys) { " " if ($phys.MediaType -eq 4) { $type = 'SSD' } " " elif ($phys.MediaType -eq 3) { $type = 'HDD' } " " else { " " if ($phys.CannotPoolReason -eq 0 -and $drive.Caption -match 'SSD') { $type = 'SSD' } " " } " "} else { " " if ($drive.Caption -match 'SSD' -or $drive.Model -match 'SSD') { $type = 'SSD' } " "}; " "[PSCustomObject]@{ device = $letter; size_gb = $sizeGb; type = $type } " "} | ConvertTo-Json" ) cmd = f'powershell -NoProfile -ExecutionPolicy Bypass -Command "{ps_script}"' out = subprocess.check_output(cmd, shell=True, text=True, stderr=subprocess.DEVNULL) if out.strip(): raw_json = json.loads(out) items = raw_json if isinstance(raw_json, list) else [raw_data] if 'raw_data' in locals() else [raw_json] for item in items: if not isinstance(item, dict): continue drives.append({ "device": str(item.get("device", "")), "size_gb": int(item.get("size_gb", 0)), "type": str(item.get("type", "HDD")).upper() }) elif sys_name == "darwin": import subprocess import re # system_profiler SPStorageDataType возвращает структурированный текст обо всех дисках cmd = "system_profiler SPStorageDataType" out = subprocess.check_output(cmd, shell=True, text=True, stderr=subprocess.DEVNULL) # Разбиваем вывод на блоки отдельных дисков disk_blocks = out.split("\n\n") for block in disk_blocks: if "Mount Point:" in block: # Извлекаем точку монтирования (например, "/") mount_match = re.search(r"Mount Point:\s+(.+)", block) size_match = re.search(r"Capacity:\s+(\d+[\.,]\d+)\s*(GB|TB)", block) medium_match = re.search(r"Medium Type:\s+(.+)", block) if mount_match and size_match: device = mount_match.group(1).strip() # Парсим объем диска raw_size = float(size_match.group(1).replace(",", ".")) size_gb = round(raw_size * 1024) if "TB" in size_match.group(2) else round(raw_size) # Вычисляем физический тип (Mac возвращает Solid State или Rotational) phys_type = "SSD" if medium_match: medium_str = medium_match.group(1).lower() if "rotational" in medium_str or "hdd" in medium_str: phys_type = "HDD" drives.append({ "device": device, "size_gb": size_gb, "type": phys_type }) else: # Linux import subprocess import re # lsblk -d (только физические устройства) -o (колонки Имя, Размер, Вращение) out = subprocess.check_output(["lsblk", "-d", "-o", "NAME,SIZE,ROTA"], text=True, stderr=subprocess.DEVNULL) for line in out.splitlines()[1:]: parts = line.split() if len(parts) >= 3: name, size_str, rota = parts[0], parts[1], parts[2] # Парсим строковый размер lsblk (например, "465,8G" или "1T") size_gb = 500 size_match = re.search(r"(\d+[\.,]?\d*)([GMT])", size_str) if size_match: val = float(size_match.group(1).replace(",", ".")) unit = size_match.group(2) size_gb = round(val * 1024) if unit == "T" else round(val) # Если ROTA == 1 -> диск вращается (HDD), если 0 -> твердотельный (SSD) phys_type = "HDD" if rota == "1" else "SSD" drives.append({ "device": f"/dev/{name}", "size_gb": size_gb, "type": phys_type }) except Exception: pass return drives if drives else [{"device": "C:", "size_gb": 512, "type": "SSD"}]
[документация] @classmethod def clear(cls) -> None: pass
[документация] @classmethod def destroy(cls) -> None: pass