hwdetect 1.0.0__tar.gz

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.
@@ -0,0 +1,7 @@
1
+ Metadata-Version: 2.4
2
+ Name: hwdetect
3
+ Version: 1.0.0
4
+ Summary: A hybrid C/Python hardware detection package.
5
+ Author: codingmaster24
6
+ Dynamic: author
7
+ Dynamic: summary
@@ -0,0 +1,31 @@
1
+ sudo apt update
2
+ sudo apt install python3-pip
3
+
4
+ python3 -m pip install -e .
5
+
6
+ pip3 install -e .
7
+
8
+ # Install the package locally in editable mode (great for testing)
9
+ pip install -e .
10
+
11
+ # OR install it normally
12
+ pip install .
13
+
14
+ hwdetect
15
+
16
+ # 1. Create a virtual environment named "venv"
17
+ python3 -m venv venv
18
+
19
+ # 2. Activate the virtual environment
20
+ source venv/bin/activate
21
+
22
+ # 3. Now install your package
23
+ pip install -e .
24
+
25
+ sudo apt install python3.14-venv
26
+
27
+ python3 -m venv venv
28
+
29
+ source venv/bin/activate
30
+
31
+ pip install -e .
File without changes
@@ -0,0 +1,180 @@
1
+ /*
2
+ * hardware_detect_base.c
3
+ * Compile: gcc -O2 hardware_detect_base.c -o hardware_detect_base
4
+ * Run: ./hardware_detect_base
5
+ */
6
+
7
+ #include <stdio.h>
8
+ #include <stdlib.h>
9
+ #include <string.h>
10
+ #include <cpuid.h>
11
+ #include <sys/utsname.h>
12
+ #include <sys/sysinfo.h>
13
+ #include <unistd.h>
14
+ #include <fcntl.h>
15
+ #include <dirent.h>
16
+
17
+ // Helper to read sysfs/proc text files safely
18
+ void read_sysfs_value(const char *path, char *buffer, size_t max_len) {
19
+ int fd = open(path, O_RDONLY);
20
+ if (fd < 0) {
21
+ snprintf(buffer, max_len, "N/A (Requires Root or Unsupported)");
22
+ return;
23
+ }
24
+ ssize_t bytes = read(fd, buffer, max_len - 1);
25
+ if (bytes > 0) {
26
+ buffer[bytes] = '\0';
27
+ // Strip trailing newline
28
+ char *newline = strchr(buffer, '\n');
29
+ if (newline) *newline = '\0';
30
+ } else {
31
+ snprintf(buffer, max_len, "N/A");
32
+ }
33
+ close(fd);
34
+ }
35
+
36
+ // 1. CPU Detection using x86 CPUID Assembly & Standard Headers
37
+ void detect_cpu() {
38
+ printf("========================================\n");
39
+ printf(" CPU CONFIGURATION \n");
40
+ printf("========================================\n");
41
+
42
+ unsigned int eax, ebx, ecx, edx;
43
+
44
+ // CPU Vendor String (Leaf 0x00000000)
45
+ char vendor[13] = {0};
46
+ __cpuid(0, eax, ebx, ecx, edx);
47
+ *(unsigned int *)&vendor[0] = ebx;
48
+ *(unsigned int *)&vendor[4] = edx;
49
+ *(unsigned int *)&vendor[8] = ecx;
50
+ printf("CPU Vendor : %s\n", vendor);
51
+
52
+ // CPU Brand String via Assembly (Leaves 0x80000002, 0x80000003, 0x80000004)
53
+ char brand[49] = {0};
54
+ unsigned int *bptr = (unsigned int *)brand;
55
+ for (unsigned int leaf = 0x80000002; leaf <= 0x80000004; ++leaf) {
56
+ __cpuid(leaf, eax, ebx, ecx, edx);
57
+ *bptr++ = eax;
58
+ *bptr++ = ebx;
59
+ *bptr++ = ecx;
60
+ *bptr++ = edx;
61
+ }
62
+ printf("CPU Model : %s\n", brand[0] ? brand : "Unknown");
63
+
64
+ // Cores and Threads from system headers
65
+ long proc_online = sysconf(_SC_NPROCESSORS_ONLN);
66
+ long proc_conf = sysconf(_SC_NPROCESSORS_CONF);
67
+ printf("Logical Threads : %ld\n", proc_online);
68
+ printf("Configured Cores: %ld\n", proc_conf);
69
+ }
70
+
71
+ // 2. RAM Detection using <sys/sysinfo.h> & /proc/meminfo
72
+ void detect_ram() {
73
+ printf("\n========================================\n");
74
+ printf(" RAM CONFIGURATION \n");
75
+ printf("========================================\n");
76
+
77
+ struct sysinfo si;
78
+ if (sysinfo(&si) == 0) {
79
+ unsigned long total_ram = (si.totalram * si.mem_unit) / (1024 * 1024);
80
+ unsigned long free_ram = (si.freeram * si.mem_unit) / (1024 * 1024);
81
+ unsigned long avail_ram = (si.freeram + si.bufferram) * si.mem_unit / (1024 * 1024);
82
+
83
+ printf("Total Memory : %lu MB (%.2f GB)\n", total_ram, total_ram / 1024.0);
84
+ printf("Free Memory : %lu MB\n", free_ram);
85
+ printf("Available Memory: %lu MB\n", avail_ram);
86
+ }
87
+
88
+ // Module Specs via DMI Sysfs
89
+ char ram_type[64], ram_speed[64];
90
+ read_sysfs_value("/sys/class/dmi/id/memory_device_type", ram_type, sizeof(ram_type));
91
+ read_sysfs_value("/sys/class/dmi/id/memory_device_speed", ram_speed, sizeof(ram_speed));
92
+ printf("DMI Memory Type : %s\n", ram_type);
93
+ printf("DMI Speed : %s\n", ram_speed);
94
+ }
95
+
96
+ // 3. Motherboard Detection via Sysfs DMI tables
97
+ void detect_motherboard() {
98
+ printf("\n========================================\n");
99
+ printf(" MOTHERBOARD CONFIGURATION \n");
100
+ printf("========================================\n");
101
+
102
+ char vendor[128], product[128], version[128], bios_ver[128];
103
+ read_sysfs_value("/sys/class/dmi/id/board_vendor", vendor, sizeof(vendor));
104
+ read_sysfs_value("/sys/class/dmi/id/board_name", product, sizeof(product));
105
+ read_sysfs_value("/sys/class/dmi/id/board_version", version, sizeof(version));
106
+ read_sysfs_value("/sys/class/dmi/id/bios_version", bios_ver, sizeof(bios_ver));
107
+
108
+ printf("Manufacturer : %s\n", vendor);
109
+ printf("Board Model : %s\n", product);
110
+ printf("Board Revision : %s\n", version);
111
+ printf("BIOS Version : %s\n", bios_ver);
112
+ }
113
+
114
+ // 4. GPU Detection via PCI Bus Scanning (/sys/bus/pci/devices)
115
+ void detect_gpu() {
116
+ printf("\n========================================\n");
117
+ printf(" GPU CONFIGURATION \n");
118
+ printf("========================================\n");
119
+
120
+ DIR *dir = opendir("/sys/bus/pci/devices");
121
+ if (!dir) {
122
+ printf("Cannot access PCI bus.\n");
123
+ return;
124
+ }
125
+
126
+ struct dirent *entry;
127
+ int count = 0;
128
+ while ((entry = readdir(dir)) != NULL) {
129
+ if (entry->d_name[0] == '.') continue;
130
+
131
+ char class_path[512], class_buf[32] = {0};
132
+ snprintf(class_path, sizeof(class_path), "/sys/bus/pci/devices/%s/class", entry->d_name);
133
+ read_sysfs_value(class_path, class_buf, sizeof(class_buf));
134
+
135
+ // Display Controller Class Prefix: 0x030000 (VGA) or 0x030200 (3D Controller)
136
+ if (strncmp(class_buf, "0x03", 4) == 0) {
137
+ count++;
138
+ char vendor_path[512], device_path[512];
139
+ char vendor_id[32] = {0}, device_id[32] = {0};
140
+
141
+ snprintf(vendor_path, sizeof(vendor_path), "/sys/bus/pci/devices/%s/vendor", entry->d_name);
142
+ snprintf(device_path, sizeof(device_path), "/sys/bus/pci/devices/%s/device", entry->d_name);
143
+ read_sysfs_value(vendor_path, vendor_id, sizeof(vendor_id));
144
+ read_sysfs_value(device_path, device_id, sizeof(device_id));
145
+
146
+ printf("[GPU #%d]\n", count);
147
+ printf(" PCI Slot ID : %s\n", entry->d_name);
148
+ printf(" Vendor ID : %s\n", vendor_id);
149
+ printf(" Device ID : %s\n", device_id);
150
+ printf(" Device Class : %s\n", class_buf);
151
+ }
152
+ }
153
+ closedir(dir);
154
+ if (count == 0) printf("No PCI Display Adapters found.\n");
155
+ }
156
+
157
+ // 5. Operating System Specifications using <sys/utsname.h>
158
+ void detect_os() {
159
+ printf("\n========================================\n");
160
+ printf(" OS & KERNEL SPEC \n");
161
+ printf("========================================\n");
162
+
163
+ struct utsname os_info;
164
+ if (uname(&os_info) == 0) {
165
+ printf("OS Kernel Name : %s\n", os_info.sysname);
166
+ printf("Node Hostname : %s\n", os_info.nodename);
167
+ printf("Kernel Release : %s\n", os_info.release);
168
+ printf("Kernel Version : %s\n", os_info.version);
169
+ printf("Architecture : %s\n", os_info.machine);
170
+ }
171
+ }
172
+
173
+ int main() {
174
+ detect_os();
175
+ detect_cpu();
176
+ detect_ram();
177
+ detect_motherboard();
178
+ detect_gpu();
179
+ return 0;
180
+ }
@@ -0,0 +1,154 @@
1
+ import os
2
+ import glob
3
+ import ctypes
4
+ import struct
5
+
6
+ def read_file(path):
7
+ try:
8
+ with open(path, "r") as f:
9
+ return f.read().strip()
10
+ except Exception:
11
+ return "N/A"
12
+
13
+ # 1. OS & Kernel (via C libc uname call)
14
+ class UNameStruct(ctypes.Structure):
15
+ _fields_ = [
16
+ ('sysname', ctypes.c_char * 65),
17
+ ('nodename', ctypes.c_char * 65),
18
+ ('release', ctypes.c_char * 65),
19
+ ('version', ctypes.c_char * 65),
20
+ ('machine', ctypes.c_char * 65),
21
+ ('domainname', ctypes.c_char * 65)
22
+ ]
23
+
24
+ def detect_os():
25
+ print("=" * 45)
26
+ print(" OS & KERNEL SPEC ")
27
+ print("=" * 45)
28
+ try:
29
+ libc = ctypes.CDLL("libc.so.6")
30
+ buf = UNameStruct()
31
+ if libc.uname(ctypes.byref(buf)) == 0:
32
+ print(f"OS Kernel Name : {buf.sysname.decode()}")
33
+ print(f"Hostname : {buf.nodename.decode()}")
34
+ print(f"Kernel Release : {buf.release.decode()}")
35
+ print(f"Architecture : {buf.machine.decode()}")
36
+ except Exception as e:
37
+ print(f"Could not execute libc.uname: {e}")
38
+
39
+ # 2. CPU Specs (Reading raw CPU brand/topology from kernel sysfs)
40
+ def detect_cpu():
41
+ print("\n" + "=" * 45)
42
+ print(" CPU CONFIGURATION ")
43
+ print("=" * 45)
44
+
45
+ # Read model name from sysfs/proc directly
46
+ cpu_model = "Unknown"
47
+ if os.path.exists("/proc/cpuinfo"):
48
+ with open("/proc/cpuinfo", "r") as f:
49
+ for line in f:
50
+ if "model name" in line:
51
+ cpu_model = line.split(":")[1].strip()
52
+ break
53
+
54
+ logical_threads = os.cpu_count() or 0
55
+
56
+ # Calculate physical cores by parsing core IDs
57
+ core_ids = set()
58
+ for cpu_dir in glob.glob("/sys/devices/system/cpu/cpu[0-9]*"):
59
+ core_id = read_file(f"{cpu_dir}/topology/core_id")
60
+ if core_id != "N/A":
61
+ core_ids.add(core_id)
62
+
63
+ physical_cores = len(core_ids) if core_ids else "N/A"
64
+
65
+ print(f"CPU Model : {cpu_model}")
66
+ print(f"Physical Cores : {physical_cores}")
67
+ print(f"Logical Threads : {logical_threads}")
68
+
69
+ # 3. RAM Specs (via libc sysinfo and /proc/meminfo)
70
+ class SysInfoStruct(ctypes.Structure):
71
+ _fields_ = [
72
+ ('uptime', ctypes.c_long),
73
+ ('loads', ctypes.c_ulong * 3),
74
+ ('totalram', ctypes.c_ulong),
75
+ ('freeram', ctypes.c_ulong),
76
+ ('sharedram', ctypes.c_ulong),
77
+ ('bufferram', ctypes.c_ulong),
78
+ ('totalswap', ctypes.c_ulong),
79
+ ('freeswap', ctypes.c_ulong),
80
+ ('procs', ctypes.c_ushort),
81
+ ('totalhigh', ctypes.c_ulong),
82
+ ('freehigh', ctypes.c_ulong),
83
+ ('mem_unit', ctypes.c_uint)
84
+ ]
85
+
86
+ def detect_ram():
87
+ print("\n" + "=" * 45)
88
+ print(" RAM CONFIGURATION ")
89
+ print("=" * 45)
90
+ try:
91
+ libc = ctypes.CDLL("libc.so.6")
92
+ info = SysInfoStruct()
93
+ if libc.sysinfo(ctypes.byref(info)) == 0:
94
+ unit = info.mem_unit if info.mem_unit > 0 else 1
95
+ total_gb = (info.totalram * unit) / (1024 ** 3)
96
+ free_gb = (info.freeram * unit) / (1024 ** 3)
97
+ print(f"Total RAM : {total_gb:.2f} GB")
98
+ print(f"Free RAM : {free_gb:.2f} GB")
99
+ except Exception as e:
100
+ print(f"Error fetching memory via libc: {e}")
101
+
102
+ # Read RAM module hardware details from DMI tables
103
+ ram_type = read_file("/sys/class/dmi/id/memory_device_type")
104
+ ram_speed = read_file("/sys/class/dmi/id/memory_device_speed")
105
+ print(f"Memory Type : {ram_type}")
106
+ print(f"Memory Speed : {ram_speed}")
107
+
108
+ # 4. Motherboard Specs
109
+ def detect_motherboard():
110
+ print("\n" + "=" * 45)
111
+ print(" MOTHERBOARD CONFIGURATION ")
112
+ print("=" * 45)
113
+ vendor = read_file("/sys/class/dmi/id/board_vendor")
114
+ product = read_file("/sys/class/dmi/id/board_name")
115
+ version = read_file("/sys/class/dmi/id/board_version")
116
+ bios = read_file("/sys/class/dmi/id/bios_version")
117
+
118
+ print(f"Manufacturer : {vendor}")
119
+ print(f"Product Name : {product}")
120
+ print(f"Board Revision : {version}")
121
+ print(f"BIOS Version : {bios}")
122
+
123
+ # 5. GPU Specs (PCI Bus Scan via /sys/bus/pci/devices)
124
+ def detect_gpu():
125
+ print("\n" + "=" * 45)
126
+ print(" GPU CONFIGURATION ")
127
+ print("=" * 45)
128
+ gpu_devices = []
129
+ pci_devices = glob.glob("/sys/bus/pci/devices/*")
130
+
131
+ for dev in pci_devices:
132
+ cls = read_file(f"{dev}/class")
133
+ # Match PCI class 0x030000 (VGA) or 0x030200 (3D Controller)
134
+ if cls.startswith("0x03"):
135
+ vendor_id = read_file(f"{dev}/vendor")
136
+ device_id = read_file(f"{dev}/device")
137
+ gpu_devices.append((dev.split("/")[-1], vendor_id, device_id, cls))
138
+
139
+ if gpu_devices:
140
+ for idx, (slot, vendor, device, dev_cls) in enumerate(gpu_devices, 1):
141
+ print(f"[GPU #{idx}]")
142
+ print(f" PCI Bus Address: {slot}")
143
+ print(f" Vendor ID : {vendor}")
144
+ print(f" Device ID : {device}")
145
+ print(f" Class Code : {dev_cls}")
146
+ else:
147
+ print("No PCI GPU devices detected.")
148
+
149
+ if __name__ == "__main__":
150
+ detect_os()
151
+ detect_cpu()
152
+ detect_ram()
153
+ detect_motherboard()
154
+ detect_gpu()
@@ -0,0 +1,52 @@
1
+ import os
2
+ import subprocess
3
+ import logging
4
+ from . import hardware_detect_base_py
5
+
6
+ # Configure Logging
7
+ logging.basicConfig(
8
+ level=logging.INFO,
9
+ format='%(asctime)s - %(levelname)s - %(message)s',
10
+ datefmt='%Y-%m-%d %H:%M:%S'
11
+ )
12
+ logger = logging.getLogger("HWDetect")
13
+
14
+ def run_hardware_detect():
15
+ # Locate the directory where this package is installed
16
+ base_dir = os.path.dirname(os.path.abspath(__file__))
17
+ c_binary = os.path.join(base_dir, 'hardware_detect_base')
18
+
19
+ logger.info("Attempting to detect hardware using low-level C binary...")
20
+
21
+ try:
22
+ if not os.path.exists(c_binary):
23
+ raise FileNotFoundError("C binary not found. It may have failed to compile during installation.")
24
+
25
+ # Execute the C binary and capture the output
26
+ result = subprocess.run([c_binary], capture_output=True, text=True, check=True)
27
+ print(result.stdout)
28
+ logger.info("Hardware detection completed successfully using C binary.")
29
+
30
+ except subprocess.CalledProcessError as e:
31
+ logger.warning(f"C binary executed but returned an error (Code {e.returncode}).")
32
+ logger.debug(f"C binary stderr: {e.stderr}")
33
+ _run_python_fallback()
34
+
35
+ except Exception as e:
36
+ logger.warning(f"C binary execution failed: {e}")
37
+ _run_python_fallback()
38
+
39
+ def _run_python_fallback():
40
+ logger.info("Falling back to Python-based hardware detection...")
41
+ try:
42
+ hardware_detect_base_py.detect_os()
43
+ hardware_detect_base_py.detect_cpu()
44
+ hardware_detect_base_py.detect_ram()
45
+ hardware_detect_base_py.detect_motherboard()
46
+ hardware_detect_base_py.detect_gpu()
47
+ logger.info("Hardware detection completed successfully using Python fallback.")
48
+ except Exception as e:
49
+ logger.error(f"Critical Failure: Python fallback also failed. Exception: {e}")
50
+
51
+ if __name__ == "__main__":
52
+ run_hardware_detect()
@@ -0,0 +1,7 @@
1
+ Metadata-Version: 2.4
2
+ Name: hwdetect
3
+ Version: 1.0.0
4
+ Summary: A hybrid C/Python hardware detection package.
5
+ Author: codingmaster24
6
+ Dynamic: author
7
+ Dynamic: summary
@@ -0,0 +1,12 @@
1
+ README.md
2
+ setup.py
3
+ hwdetect/__init__.py
4
+ hwdetect/hardware_detect_base
5
+ hwdetect/hardware_detect_base.c
6
+ hwdetect/hardware_detect_base_py.py
7
+ hwdetect/main.py
8
+ hwdetect.egg-info/PKG-INFO
9
+ hwdetect.egg-info/SOURCES.txt
10
+ hwdetect.egg-info/dependency_links.txt
11
+ hwdetect.egg-info/entry_points.txt
12
+ hwdetect.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ hwdetect = hwdetect.main:run_hardware_detect
@@ -0,0 +1 @@
1
+ hwdetect
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,41 @@
1
+ import os
2
+ import subprocess
3
+ from setuptools import setup, find_packages
4
+ from setuptools.command.build_py import build_py
5
+
6
+ class CustomBuildCommand(build_py):
7
+ """Custom build command to compile the C source during pip install."""
8
+ def run(self):
9
+ # Paths for the C source and the output binary
10
+ c_source = os.path.join('hwdetect', 'hardware_detect_base.c')
11
+ c_binary = os.path.join('hwdetect', 'hardware_detect_base')
12
+
13
+ try:
14
+ print(f"Compiling {c_source} using GCC...")
15
+ subprocess.check_call(['gcc', '-O2', c_source, '-o', c_binary])
16
+ print("C binary compiled successfully.")
17
+ except Exception as e:
18
+ print(f"WARNING: Failed to compile C source. The package will rely on the Python fallback. Error: {e}")
19
+
20
+ # Continue with the standard Python package build process
21
+ super().run()
22
+
23
+ setup(
24
+ name="hwdetect",
25
+ version="1.0.0",
26
+ description="A hybrid C/Python hardware detection package.",
27
+ author="codingmaster24",
28
+ packages=find_packages(),
29
+ # Ensure the compiled binary is included in the final package
30
+ package_data={'hwdetect': ['hardware_detect_base', 'hardware_detect_base.c']},
31
+ include_package_data=True,
32
+ cmdclass={
33
+ 'build_py': CustomBuildCommand,
34
+ },
35
+ # This creates a terminal command you can run from anywhere
36
+ entry_points={
37
+ 'console_scripts': [
38
+ 'hwdetect=hwdetect.main:run_hardware_detect',
39
+ ],
40
+ },
41
+ )