feat(refactor): refactored code

the code from earlier was a class ridden sloppy mess with a bug in one part.

i have refactored it to only contain one class full of the data needed, and added some personal changes which i think are nice!
This commit is contained in:
Artur Manuel 2024-08-05 02:53:32 +01:00
commit 8cc4f4e0ac
Failed to generate hash of commit
4 changed files with 113 additions and 157 deletions

View file

@ -29,21 +29,14 @@
#
# Use this shell for developing your app.
devShells.default = pkgs.mkShell {
inputsFrom = [ self.packages.${system}.whyfetch ];
inputsFrom = [
self.packages.${system}.whyfetch
pkgs.pyright
pkgs.black
pkgs.isort
];
};
apps = {
whyfetch = {
program = "${self.packages.${system}.whyfetch}/bin/whyfetch";
type = "app";
};
default = {
program = "${self.packages.${system}.default}/bin/whyfetch";
type = "app";
};
};
# Shell for poetry.
#
# nix develop .#poetry

View file

@ -1,41 +1,44 @@
import whyfetch.system_properties as w
from whyfetch.data import Data
def separator_from_longest_prop(properties: list[w.Prop]):
def separator_from_longest_prop(props: list[str]):
j: int = 0
for i in properties:
if i.length > j:
j = i.length
for i in props:
if len(i) > j:
j = len(i)
continue
else:
continue
return ""*j
colours = {
"red": "\x1b[1;31m",
"blue": "\x1b[1;34m",
"white": "\x1b[1;39m",
}
class Colours:
red: str = "\x1b[1;31m"
blue: str = "\x1b[1;34m"
white: str = "\x1b[1;39m"
magenta: str = "\x1b[1;35m"
def __main__():
kernel: w.Kernel = w.Kernel()
ram: w.Ram = w.Ram()
username: w.Username = w.Username()
os: w.Os = w.Os()
shell: w.Shell = w.Shell()
uptime: w.Uptime = w.Uptime()
locale: w.Locale = w.Locale()
d: Data = Data()
props: list[str] = [
f"{d.username}@{d.hostname}",
f"kernel: {d.kernel}",
f"os: {d.os}",
f"shell: {d.shell}",
f"ram: {d.ram}",
f"up: {d.uptime}",
f"locale: {d.locale}"
]
properties: list[w.Prop] = [ kernel.prop, ram.prop, username.prop, os.prop, uptime.prop, locale.prop ]
separator: str = separator_from_longest_prop(props)
print(f'{colours["white"]}━━━━━━━━━━━━━━━{separator_from_longest_prop(properties)}')
print(f' {colours["red"]}_.----._{colours["white"]} {username.prop.content}@{kernel.node}')
print(f' {colours["red"]}.\' \'.{colours["white"]} {kernel.prop.content}')
print(f'{colours["red"]}/{colours["white"]}._ _.--._ {colours["red"]}\\{colours["white"]} {os.prop.content}')
print(f'|_ \'-\' _.._ `| {shell.prop.content}')
print(f'{colours["blue"]}\\{colours["white"]} `---\' `-{colours["blue"]}/{colours["white"]} {ram.prop.content}')
print(f' {colours["blue"]}\'._ _.\'{colours["white"]} {uptime.prop.content}')
print(f' {colours["blue"]}\'----\'{colours["white"]} {locale.prop.content}')
print(f'━━━━━━━━━━━━━━━{separator_from_longest_prop(properties)}')
print(f'{Colours.white}━━━━━━━━━━━━━━━{separator}')
print(f' {Colours.red}_.----._{Colours.white} {Colours.magenta}{d.username}{Colours.white}@{Colours.magenta}{d.hostname}')
print(f' {Colours.red}.\' \'.{Colours.white} {Colours.magenta}kernel:{Colours.white} {d.kernel}')
print(f'{Colours.red}/{Colours.white}._ _.--._ {Colours.red}\\{Colours.white} {Colours.magenta}os:{Colours.white} {d.os}')
print(f'|_ \'-\' _.._ `| {Colours.magenta}shell:{Colours.white} {d.shell}')
print(f'{Colours.blue}\\{Colours.white} `---\' `-{Colours.blue}/{Colours.white} {Colours.magenta}ram:{Colours.white} {d.ram}')
print(f' {Colours.blue}\'._ _.\'{Colours.white} {Colours.magenta}up:{Colours.white} {d.uptime}')
print(f' {Colours.blue}\'----\'{Colours.white} {Colours.magenta}locale:{Colours.white} {d.locale}')
print(f'━━━━━━━━━━━━━━━{separator}')

76
whyfetch/data.py Normal file
View file

@ -0,0 +1,76 @@
from typing import Callable, NamedTuple
import getpass as gp
import socket as sk
import platform as pl
import psutil as ps
import shellingham as sh
import locale as lc
import datetime as dt
import time as tm
import os
ures: pl.uname_result = pl.uname()
sys: str = pl.system()
class Data:
def __init__(self) -> None:
self.username: str = gp.getuser()
self.hostname: str = sk.gethostname()
self.kernel: str = f"{ures.system} {ures.release} {ures.machine}"
self.os: str = self.get_os()
self.shell: str = self.get_shell()
self.ram: str = self.get_ram()
self.uptime: str = self.get_uptime()
self.locale: str = lc.setlocale(lc.LC_CTYPE)
pass
def get_os(self) -> str:
if "Linux" == ures.system:
linux_res: dict[str, str] = pl.freedesktop_os_release()
return linux_res['PRETTY_NAME']
if [ "FreeBSD", "OpenBSD", "NetBSD" ] not in [ ures.system ]:
return ures.system
if sys == "Darwin":
mac_res: tuple[str, tuple[str, str, str], str] = pl.mac_ver()
mac_release: str = mac_res[0]
mac_version: str = mac_res[1][0]
return f"{mac_release} {mac_version}"
if sys == "Windows":
win_res: tuple[str, str, str, str] = pl.win32_ver()
win_edition: str = pl.win32_edition()
win_release: str = win_res[0]
win_ver: str = win_res[1]
return f"{win_release} {win_edition} {win_ver}"
raise ValueError("Unknown operating system. %r" % sys)
def get_shell(self) -> str:
try:
shell_info = sh.detect_shell()
shell: str = shell_info[0]
except sh.ShellDetectionFailure:
shell: str = provide_default_shell()
return shell
def get_ram(self) -> str:
to_gb: Callable[[int], float] = lambda s: s / (1024 ** 3)
vm: NamedTuple = ps.virtual_memory()
total: float = to_gb(vm.total)
used: float = to_gb(vm.used)
percent: int = int(vm.percent)
return f"{used:.1f}GB / {total:.1f}GB ({percent}%)"
def get_uptime(self) -> str:
current_uptime: tm.struct_time = tm.gmtime(tm.time() - ps.boot_time())
return tm.strftime("%H hours, %M minutes, %S seconds", current_uptime)
def provide_default_shell() -> str:
if os.name == 'nt':
return os.environ['COMSPEC']
elif os.name == 'posix':
return os.environ['SHELL']
raise NotImplementedError(f'OS {os.name!r} support not available')

View file

@ -1,116 +0,0 @@
import platform
import psutil
import os
from sys import platform as platform2
import csv
import pathlib
import shellingham as shelling
import time
import locale
uname = platform.uname()
svmem = psutil.virtual_memory()
b_to_mb = lambda s : int(s / pow(1024, 2))
class Prop:
def __init__(self, content) -> None:
self.content = content
self.length = len(self.content)
pass
class Kernel:
def __init__(self) -> None:
self.system: str = uname.system
self.release: str = uname.release
self.machine: str = uname.machine
self.node: str = uname.node
self.prop: Prop = Prop(f"kernel: {self.system} {self.release} {self.machine}")
pass
class Ram:
def __init__(self) -> None:
self.total: int = svmem.total
self.used: int = svmem.used
self.available = svmem.available
self.prop: Prop = Prop(self.format())
pass
def format(self) -> str:
total_in_gb: int = b_to_mb(self.total)
used_in_gb: int = b_to_mb(self.used)
available_in_gb: int = b_to_mb(self.available)
return f"ram: {used_in_gb}MB/{total_in_gb}MB ({available_in_gb}MB free)"
class Username:
def __init__(self) -> None:
content: str = self.get_username()
self.prop: Prop = Prop(content)
pass
def get_username(self) -> str:
username: str = ""
user_home: str = os.path.expanduser('~')
if platform2 == "win32":
username = user_home.split("\\")[-1]
else:
username = user_home.split("/")[-1]
return username
class Os:
def __init__(self) -> None:
content: str = self.get_os_pretty_name()
self.prop: Prop = Prop(content)
pass
def get_os_pretty_name(self) -> str:
path = pathlib.Path("/etc/os-release")
with open(path) as stream:
reader = csv.reader(stream, delimiter="=")
os_release = dict(reader)
return f"os: {os_release['PRETTY_NAME']}"
class Shell:
def __init__(self) -> None:
content: str = self.get_shell()
self.prop: Prop = Prop(content)
pass
def get_shell(self) -> str:
try:
shell = shelling.detect_shell()
except shelling.shellDetectionFailure:
shell = self.provide_default()
return f"shell: {shell[0]}"
def provide_default():
if os.name == 'posix':
return os.environ['SHELL']
elif os.name == 'nt':
return os.environ['COMSPEC']
raise NotImplementedError(f'OS {os.name!r} support not available')
class Uptime:
def __init__(self) -> None:
content: str = f"up: {self.get_uptime()}"
self.prop = Prop(content)
pass
def get_uptime(self) -> str:
seconds_elapsed = time.time() - psutil.boot_time()
seconds: int = int(seconds_elapsed % 60)
minutes: int = int(seconds_elapsed / 60) % 60
hours: int = int(seconds_elapsed / pow(60, 2))
return f"{hours} hours, {minutes} minutes and {seconds} seconds"
class Locale:
def __init__(self) -> None:
content: str = f"locale: {locale.setlocale(locale.LC_CTYPE)}"
self.prop: Prop = Prop(content)
pass