Upload the skeleton of the program

This commit is contained in:
VetheonGames 2023-09-21 18:03:25 -06:00
parent 0155a38171
commit 2f72d0a133
15 changed files with 427 additions and 0 deletions

9
Gemfile Normal file
View File

@ -0,0 +1,9 @@
# frozen_string_literal: true
source "https://rubygems.org"
# gem "rails"
gem "tty-prompt", "~> 0.23.1"
gem "speedtest_net", "~> 0.9.2"

37
Gemfile.lock Normal file
View File

@ -0,0 +1,37 @@
GEM
remote: https://rubygems.org/
specs:
curb (1.0.5)
ethon (0.16.0)
ffi (>= 1.15.0)
ffi (1.15.5)
pastel (0.8.0)
tty-color (~> 0.5)
rexml (3.2.6)
speedtest_net (0.9.2)
curb (>= 0.9, < 2.0)
rexml (~> 3.2)
typhoeus (~> 1.3)
tty-color (0.6.0)
tty-cursor (0.7.1)
tty-prompt (0.23.1)
pastel (~> 0.8)
tty-reader (~> 0.8)
tty-reader (0.9.0)
tty-cursor (~> 0.7)
tty-screen (~> 0.8)
wisper (~> 2.0)
tty-screen (0.8.1)
typhoeus (1.4.0)
ethon (>= 0.9.0)
wisper (2.0.1)
PLATFORMS
x86_64-linux
DEPENDENCIES
speedtest_net (~> 0.9.2)
tty-prompt (~> 0.23.1)
BUNDLED WITH
2.4.10

15
bin/systeminfo Normal file
View File

@ -0,0 +1,15 @@
#!/usr/bin/env ruby
require_relative '../lib/config_handler'
require_relative '../lib/first_run'
require_relative '../lib/commands'
# Check for config file and create if not exists
config_path = './config/systeminfo_config.yml'
ConfigHandler.ensure_config_exists(config_path)
# Load config
config = ConfigHandler.load_config(config_path)
# Handle command-line arguments
Commands.handle(ARGV, config)

37
lib/commands.rb Normal file
View File

@ -0,0 +1,37 @@
require_relative 'cpu_info'
require_relative 'ram_info'
require_relative 'disk_info'
require_relative 'gpu_info'
require_relative 'kernel_info'
require_relative 'network_info'
require_relative 'nic_info'
require_relative 'os_info'
require_relative 'uptime_info'
require_relative 'config_handler' # Add this line to require the ConfigHandler class
# ... other requires
module Commands
def self.handle(args, config)
if args.include?('--clean') || args.include?('-c')
# Remove the existing config file
config_path = './config/systeminfo_config.yml'
File.delete(config_path) if File.exist?(config_path)
# Print message and exit
puts 'Configuration file has been removed. Please re-run the system to generate a new configuration.'
exit
end
return unless args.empty?
system_info = {}
# Run the system info display
system_info[:cpu] = CpuInfo.new.gather_info if config['cpu']
system_info[:ram] = RamInfo.new.gather_info if config['ram']
# ... other info gathering
# Pass the collected data to a display handler
DisplayHandler.display(system_info)
end
end

25
lib/config_handler.rb Normal file
View File

@ -0,0 +1,25 @@
require 'yaml'
require_relative 'first_run'
class ConfigHandler
def self.ensure_config_exists(path)
return unless !File.exist?(path) || !config_valid?(path)
# Call FirstRun setup to create the config based on user input
FirstRun.setup(path)
end
def self.config_valid?(path)
# Add your validation logic here. For example, check if all keys exist.
config = YAML.load(File.read(path))
# Assuming you have a list of all valid keys
valid_keys = %w[cpu ram gpu nic_model network_speed os_name kernel_name_version system_uptime disks]
(valid_keys - config.keys).empty?
rescue StandardError
false
end
def self.load_config(path)
YAML.load(File.read(path))
end
end

38
lib/cpu_info.rb Normal file
View File

@ -0,0 +1,38 @@
# frozen_string_literal: true
class CpuInfo
def gather_info
cpu_info = {}
cores = 0
threads = 0
File.open('/proc/cpuinfo', 'r') do |f|
f.each_line do |line|
key, value = line.split(':')
next unless key && value
key = key.strip
value = value.strip
# Count the number of cores and threads
cores += 1 if key == 'core id'
threads += 1 if key == 'processor'
# Filter out the specific information
case key
when 'model name'
cpu_info[:model] = value
when 'cpu MHz'
speed_ghz = (value.to_f * 1e-3).round(2)
cpu_info[:speed] = "#{speed_ghz} GHz"
when 'cache size'
cpu_info[:l3_cache] = value if value.include?('L3')
end
end
end
cpu_info[:cores] = cores
cpu_info[:threads] = threads
cpu_info
end
end

23
lib/disk_info.rb Normal file
View File

@ -0,0 +1,23 @@
require 'json'
class DiskInfo
def self.gather_info
disk_info = []
# Get additional disk details using `lsblk` command
lsblk_output = `lsblk -J`.strip
lsblk_json = JSON.parse(lsblk_output)
lsblk_json['blockdevices'].each do |device|
next unless device['type'] == 'disk' # We only want disk devices
disk = {
model: device['model'],
type: device['rota'] == '1' ? 'HDD' : 'SSD',
transport: device['tran']
}
disk_info << disk
end
disk_info
end
end

45
lib/first_run.rb Normal file
View File

@ -0,0 +1,45 @@
require 'yaml'
require 'tty-prompt'
class FirstRun
def self.setup(config_path)
prompt = TTY::Prompt.new
puts "Welcome to SystemInfo! Let's set up your configuration."
config = {
'cpu' => prompt.yes?('Do you want to display CPU information, including Cores, Threads, Model, Clock Speed,
and L3 cache?'),
'ram' => prompt.yes?('Do you want to display RAM amount, usage at idle, and usage under load?'),
'gpu' => prompt.yes?('Do you want to display GPU Model, Video RAM amount, and driver version?'),
'nic_model' => prompt.yes?('Do you want to display NIC Model number, manufacturer, and max speed?'),
'network_speed' => prompt.yes?('Do you want to display current network upload and download speed?'),
'os_name' => prompt.yes?('Do you want to display the Operating System name?'),
'kernel_name_version' => prompt.yes?('Do you want to display the Kernel version?'),
'system_uptime' => prompt.yes?('Do you want to display how long the system has been on without restarting?'),
'disks' => prompt.yes?('Do you want to display disk information?'),
'display_resolution' => prompt.yes?('Do you want to display the current display resolution of each monitor?'),
'theme' => prompt.yes?('Do you want to display the current theme the system is using, if any?'),
'desktop_environment' => prompt.yes?('Do you want to display the current desktop environment the system
is using?'),
'window_manager' => prompt.yes?('Do you want to display the current window manager the system is using?'),
'terminal' => prompt.yes?('Do you want to display the current terminal emulator that the system is using?'),
'shell' => prompt.yes?('Do you want to display the current shell the terminal is using?'),
'hostname' => prompt.yes?('Do you want to display the current host name of the system?'),
'board_model' => prompt.yes?('Do you want to display the system\'s motherboard model name from DMIDecode?'),
'chipset' => prompt.yes?('Do you want to display the current chipset the system is using from DMIDecode?'),
'amount_of_monitors' => prompt.yes?('Do you want to display the amount of monitors the system currently is
using?'),
'sound_drivers' => prompt.yes?('Do you want to display which sound driver the system is using right now?'),
'sound_card' => prompt.yes?('Do you want to display the current sound card that the system is using?'),
'display_technology' => prompt.yes?('Do you want to display what display tech the monitors are using?'),
'color_bit_depth' => prompt.yes?('Do you want to display the color bit depth of the monitors the system is
using?'),
'package_managers' => prompt.yes?('Do you want to display the package manager or managers that the system is using
and how many packages are installed from each?'),
'file_systems' => prompt.yes?('Do you want to display which file systems the drives are using?')
}
File.write(config_path, config.to_yaml)
puts 'Configuration saved!'
end
end

40
lib/gpu_info.rb Normal file
View File

@ -0,0 +1,40 @@
# frozen_string_literal: true
class GpuInfo
def self.gather_info
# Initialize an empty hash to store GPU information
gpu_info = {}
# Use `lspci` to get basic GPU information
lspci_output = `lspci | grep VGA`.strip
if lspci_output && !lspci_output.empty?
# Extract the model and other details
model_match = lspci_output.match(/VGA compatible controller: (.+)$/)
gpu_info[:model] = model_match[1] if model_match
end
# Fetch Video RAM amount
vram_output = `lshw -c video | grep size`.strip
if vram_output && !vram_output.empty?
vram_match = vram_output.match(/size: (.+)$/)
gpu_info[:vram] = vram_match[1] if vram_match
end
# Fetch OpenGL driver version
driver_output = `glxinfo | grep "OpenGL version"`.strip
if driver_output && !driver_output.empty?
driver_match = driver_output.match(/OpenGL version string: (.+)$/)
gpu_info[:opengl_driver_version] = driver_match[1] if driver_match
end
# Fetch Vulkan driver version
vulkan_output = `vulkaninfo | grep "Vulkan Instance Version"`.strip
if vulkan_output && !vulkan_output.empty?
vulkan_match = vulkan_output.match(/Vulkan Instance Version: (.+)$/)
gpu_info[:vulkan_driver_version] = vulkan_match[1] if vulkan_match
end
# Return the gathered GPU information
gpu_info
end
end

15
lib/kernel_info.rb Normal file
View File

@ -0,0 +1,15 @@
# frozen_string_literal: true
class KernelInfo
def self.gather_info
# Initialize an empty hash to store kernel information
kernel_info = {}
# Use `uname` to get the kernel version
uname_output = `uname -r`.strip
kernel_info[:version] = uname_output if uname_output && !uname_output.empty?
# Return the gathered kernel information
kernel_info
end
end

13
lib/network_info.rb Normal file
View File

@ -0,0 +1,13 @@
# frozen_string_literal: true
require 'speedtest_net'
class NetworkInfo
def self.gather_info
result = SpeedtestNet.run
{
download_speed: result.pretty_download,
upload_speed: result.pretty_upload
}
end
end

33
lib/nic_info.rb Normal file
View File

@ -0,0 +1,33 @@
# frozen_string_literal: true
require 'English'
require 'json'
class NicInfo
def self.gather_info
raw_data = `lshw -class network -json 2>&1`
unless $CHILD_STATUS.success?
return [{ model: 'No permission', manufacturer: 'No permission',
max_speed: 'No permission' }]
end
parsed_data = JSON.parse(raw_data)
nic_info = []
parsed_data.each do |data|
info = {}
info[:model] = data['product']
info[:manufacturer] = data['vendor']
# Extracting max speed if available
info[:max_speed] = data['capabilities']['speed'] if data['capabilities'] && data['capabilities']['speed']
nic_info << info
end
nic_info
rescue JSON::ParserError
[{ model: 'No permission', manufacturer: 'No permission', max_speed: 'No permission' }]
end
end

36
lib/os_info.rb Normal file
View File

@ -0,0 +1,36 @@
# frozen_string_literal: true
class OsInfo
def self.gather_info
os_info = {}
# Get OS Name
os_info[:os_name] = begin
`lsb_release -d`.split(':').last.strip
rescue StandardError
'Unknown'
end
# Get Desktop Environment
env = ENV['XDG_CURRENT_DESKTOP'] || ENV['DESKTOP_SESSION'] || 'Unknown'
os_info[:desktop_environment] = env
# Get Window Manager
wm = begin
`wmctrl -m`.match(/Name: (.+)/).captures.first
rescue StandardError
'Unknown'
end
os_info[:window_manager] = wm
# Get Sound Driver
sound_driver = begin
`pactl info`.match(/Server String: (.+)/).captures.first.split('.').first
rescue StandardError
'Unknown'
end
os_info[:sound_driver] = sound_driver
os_info
end
end

31
lib/ram_info.rb Normal file
View File

@ -0,0 +1,31 @@
# frozen_string_literal: true
require 'English'
class RamInfo
def self.gather_info
ram_info = {}
# Get total and used RAM in GB
mem_data = `free -g`.split("\n")[1].split(/\s+/)
ram_info[:total_ram] = mem_data[1].to_i
ram_info[:used_ram] = mem_data[2].to_i
# Get RAM type and speed
begin
dmi_data = `sudo dmidecode -t memory`.split("\n").select { |line| line =~ /Type:|Speed:/ }
ram_info[:ram_type] = dmi_data.select { |line| line =~ /Type:/ }.first.split(':').last.strip
ram_info[:ram_speed] = dmi_data.select { |line| line =~ /Speed:/ }.first.split(':').last.strip
rescue StandardError
ram_info[:ram_type] = 'No permission'
ram_info[:ram_speed] = 'No permission'
end
# Handle permission issues
if $CHILD_STATUS.exitstatus != 0
ram_info[:ram_type] = 'No permission'
ram_info[:ram_speed] = 'No permission'
end
ram_info
end
end

30
lib/uptime_info.rb Normal file
View File

@ -0,0 +1,30 @@
# frozen_string_literal: true
class UptimeInfo
def self.gather_info
uptime_seconds = `cat /proc/uptime`.split.first.to_i
uptime_info = {}
# Calculate time components
minutes, seconds = uptime_seconds.divmod(60)
hours, minutes = minutes.divmod(60)
days, hours = hours.divmod(24)
weeks, days = days.divmod(7)
months, weeks = weeks.divmod(4)
years, months = months.divmod(12)
# Populate the hash only if the value is greater than zero
uptime_info[:years] = years if years.positive?
uptime_info[:months] = months if months.positive?
uptime_info[:weeks] = weeks if weeks.positive?
uptime_info[:days] = days if days.positive?
uptime_info[:hours] = hours if hours.positive?
uptime_info[:minutes] = minutes if minutes.positive?
uptime_info[:seconds] = seconds if seconds.positive?
# Format the uptime string
formatted_uptime = uptime_info.map { |k, v| "#{v} #{k.to_s.capitalize}" }.join(' : ')
{ uptime: formatted_uptime }
end
end