diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 5f5f385..545cead 100755 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -11,7 +11,7 @@ assignees: '' **Please run `fetchcord --debug` and send it here.** -**If you are unable to run FetchCord please run `neofetch --noart`(windows) or `neofetch -- stdout`(macos&linux)** +**If you are unable to run FetchCord please run `fastfetch -l none`(macos&linux)** # Operating system & way of installation diff --git a/.github/ISSUE_TEMPLATE/distro-de-wm-shell-hw-request.md b/.github/ISSUE_TEMPLATE/distro-de-wm-shell-hw-request.md index 157aa25..3b44098 100755 --- a/.github/ISSUE_TEMPLATE/distro-de-wm-shell-hw-request.md +++ b/.github/ISSUE_TEMPLATE/distro-de-wm-shell-hw-request.md @@ -9,7 +9,7 @@ assignees: '' # Debug info -**Please run `fetchcord --debug` and put it here. You might also want to send the output of `neofetch --noart`(windows) or `neofetch -- stdout`(macos&linux)** +**Please run `fetchcord --debug` and put it here. You might also want to send the output of `fas`(macos&linux)** # Requested item diff --git a/Examples/gui.png b/Examples/gui.png new file mode 100644 index 0000000..657d75e Binary files /dev/null and b/Examples/gui.png differ diff --git a/MANIFEST.in b/MANIFEST.in index 280dce7..8c8f958 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,4 +1,4 @@ -include *.py -include */*.py -include */*/*.py -include */*/*/*.py \ No newline at end of file +include resources/*.json +include resources/fetchcord_conf.yml +include resources/fetchcord_cmds.yml +include resources/default.conf diff --git a/README.md b/README.md index 7212f63..7c3f2ff 100755 --- a/README.md +++ b/README.md @@ -13,30 +13,30 @@ -

# Table of content + - [**Features**](#features) - [**To-Do**](#to-do) -+ **Installing** - - [Install on (gnu/)linux](#installing-on-gnulinux) - - [Install on MacOS](#installing-on-macos) - - [Install on Windows](#installing-on-windows) - + **Running** - - [Running on (gnu/)linux](#run) - - [Running on MacOS](#run-1) - - [Running on Windows](#run-2) -- [**Configuration**](#Configuration) +- **Installing** + - [Install on (gnu/)linux](#installing-on-gnulinux) + - [Install on MacOS](#installing-on-macos) + - [Install on Windows](#installing-on-windows) +- **Running** + - [Running on (gnu/)linux](#run-on-linux) + - [Running on MacOS](#run-on-macos) + - [Running on Windows](#run-on-windows) +- [**Configuration**](#configuration) - [**Arguments**](#arguments) +- [**Website**](#website) +- [**Examples**](#examples) -+ [**Examples**](#examples) - -### Features +## Features - [x] Distribution detection - + - [x] Distribution Version - [x] Package detection @@ -47,20 +47,21 @@ - [x] Detecting Window Manager/Desktop Environment -- [x] Detecting GPU/CPU and display it in a cycle (thanks to Hyper-KVM) +- [x] Detecting GPU/CPU and display it in a cycle - [x] Flatpak support -- [x] Add Snap support - - [x] Add Windows support. - [x] Detect Window Manager/Desktop Environment version - [x] Periodic polling of info such as package count, RAM usage, etc. +## To be tested -### To-Do +- [ ] Snap support + +## To-Do - [ ] Add more distributions (If your distro is not supported open an issue) @@ -70,50 +71,64 @@ - [ ] More GPUs? - ## Installing on (GNU/)Linux -NOTE: you need neofetch to be also installed for this to work. -#### Via AUR -On Arch Linux install this package for the git version: [fetchcord-git](https://aur.archlinux.org/packages/fetchcord-git/) -Do note that this version is directly from master, for the stable release use [pip](#via-pip) -#### Via Snap -On systems with snap installed, you can run `sudo snap install fetchcord --classic` to install fetchcord. +NOTE: you need fastfetch to be also installed for this to work. + +### Via pip (recommended) -Note that like the AUR version, this version is directly from master, for the stable release use [pip](#via-pip) -#### Via pip -To Install fetchcord via pip you can run `pip3 install fetchcord` +To install fetchcord via pip you can run `pip3 install fetchcord` If you want to remove FetchCord you can run `pip3 uninstall fetchcord` -### Run +### Via AUR + +On Arch Linux for the git testing version (the less stable version): [fetchcord-testing](https://aur.archlinux.org/packages/fetchcord-testing/) + +And the git version (synced with master): [fetchcord](https://aur.archlinux.org/packages/fetchcord/) + +### Via Snap + +On systems with snap installed, you can run `sudo snap install fetchcord --classic` to install fetchcord. + +Note that like the AUR version, this version is directly from master, for the stable release use [pip](#via-pip-recommended) + +### Run on Linux Once installed, simply run `fetchcord`. The program is also daemonizable meaning you can start it on boot using any method you prefer. -If you get `fetchcord: command not found`,add `export PATH="$HOME/.local/bin:$PATH"` to your bashrc, or just run `python3 -m fetchcord`. +If you get `fetchcord: command not found`,add `export PATH="$HOME/.local/bin:$PATH"` to your bashrc, or just run `python3 -m fetch_cord`. Optionally for systemd users there is a user-side `fetchcord.service` in this repo that can be installed to `~/.local/share/systemd/user/`, started and enabled on boot using `systemctl --user enable --now fetchcord`. ## Installing on MacOS -To install FetchCord, run `pip3 install FetchCord` +NOTE: you need fastfetch to be also installed for this to work. + +To install fetchcord via pip you can run `pip3 install fetchcord` -NOTE: you need neofetch to be also installed for this to work. +If you want to remove FetchCord you can run `pip3 uninstall fetchcord` + +### Run on MacOS -### Run +Once installed, simply run `fetchcord`. The program is also daemonizable meaning you can start it on boot using any method you prefer. -simply run `fetchcord` +If you get `fetchcord: command not found`,add `export PATH="$HOME/.local/bin:$PATH"` to your zshrc, or just run `python3 -m fetch_cord`. ## Installing on Windows -To install fetchcord on Windows run `python -m pip install fetchcord neofetch-win`. Alternatively, you can use the neofetch package from scoop as well (show more info at the expense of possible GPU detection, for now). +To install fetchcord on Windows run `pip3 install fetchcord` or `python3 -m pip install fetchcord`. + +### Run on Windows -### Run To run Fetchcord run `fetchcord` +If you get `fetchcord: command not found`, add your python scripts folder to your PATH or use `python3 -m fetch_cord`. + ### Configuration -On Linux you can use the neofetch config file to: +TODO Fastfetch config + ## Arguments + --nodistro, Don't show distro info. --nohardware, Don't show hardware info. @@ -144,7 +160,7 @@ default config path should be `~/.config/neofetch/config.conf` --terminal, set custom terminal (useful if using a script or dmenu). ---termfont, set custom terminal font (useful if neofetch can't get it). +--termfont, set custom terminal font (useful if fastfetch can't get it). --pause-cycle, Extra cycle that pauses FetchCord to show other activities. @@ -155,13 +171,25 @@ default config path should be `~/.config/neofetch/config.conf` --memtype, use GB or MB to show RAM. -h or --help, shows this information above. + +## Website + +Fetchcord now has a website! You can find this site over at https://fetchcord.github.io/ - please keep in mind this site is still currently work in progress though. + ## Examples ### Operating Systems + ![MacOS bigsur](Examples/mac.png) ![Windows 10](Examples/windows.png) ![Ubuntu](Examples/ubuntu.png) + ### Terminals + ![Konsole](Examples/konsole.png) ![Gnome terminal](Examples/gnometerm.png) ![Apple terminal](Examples/appleterm.png) + ### Cpus + ![Ryzen 9](Examples/ryzencpu.png) ![Intel i7](Examples/intelcpu.png) ![Intel pentium](Examples/pent.png) + ### Hosts + ![HP laptop](Examples/hp.png) ![TUF gaming laptop](Examples/tuf.png) ![Lenovo desktop](Examples/len.png) diff --git a/fetch_cord/Config.py b/fetch_cord/Config.py new file mode 100644 index 0000000..8621712 --- /dev/null +++ b/fetch_cord/Config.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python3 + +from importlib import resources +import yaml + + +class Config(dict): + def __init__(self, config_name: str = "fetchcord_conf.yml") -> None: + super(Config, self).__init__( + self.get_config(self.get_resource_path("fetch_cord.resources", config_name)) + ) + + def get_resource_path(self, package, resource: str): + with resources.path(package, resource) as path: + return path + + def get_config(self, path: str): + with open(path, "r") as stream: + try: + return yaml.safe_load(stream) + except yaml.YAMLError as exc: + print(exc) + + return None diff --git a/fetch_cord/Cycle.py b/fetch_cord/Cycle.py index 8c01dcc..1a6d568 100755 --- a/fetch_cord/Cycle.py +++ b/fetch_cord/Cycle.py @@ -1,20 +1,91 @@ -from .computer.Computer import Computer +# 1/usr/bin/env python3 + + +from threading import Event from typing import Dict +from pypresence import Presence, exceptions +import psutil class Cycle: name: str + app_id: str = None top_line: str = None bottom_line: str = None small_icon: str = None + time: str = None + + debug: bool = False + rpc: Presence = None + + stop: Event = None + + def __init__(self, config: Dict, stop: Event = None): + if stop is None: + stop = Event() + + for key in config: + setattr(self, key, config[key]) + self.stop = stop + + def __del__(self) -> None: + if self.rpc is not None: + self.rpc.close() + + def setup(self, client_id: str) -> None: + self.rpc = Presence(int(client_id)) + + def try_connect(self) -> None: + while not self.stop.is_set(): + try: + if self.debug: + print('try_connect(name="{}")'.format(self.name)) + self.rpc.connect() + break + except ConnectionRefusedError: + print( + """ +RPC connection refused (is Discord open?); trying again in 30 seconds""" + ) + self.wait(30) + + def update( + self, client_id: str, app: str, bottom: str, top: str, icon: str, icon_id: str + ): + try: + self.rpc.update( + int(client_id), + state=bottom, + details=top, + large_image="big", + large_text=app, + small_image=icon_id, + small_text=icon, + start=psutil.boot_time(), + ) + + self.wait(int(self.time)) + + self.rpc.close() + # ConnectionResetError is here to avoid crashing + # if Discord is still just starting + except (ConnectionResetError, exceptions.InvalidID): + pass + + def wait(self, n: float, interval_duration: float = 0.05) -> None: + """Wait for n seconds or until interrupted.""" - def __init__(self, name: str, config: Dict[str, str], computer: Computer): - self.name = name + intervals = int(n / interval_duration) + for _ in range(intervals): + if self.stop.wait(interval_duration): + break - if "top_line" in config["top_line"]: - self.top_line = config["top_line"] - if "bottom_line" in config["bottom_line"]: - self.bottom_line = config["bottom_line"] - if "small_icon" in config["small_icon"]: - self.small_icon = config["small_icon"] \ No newline at end of file + def __repr__(self) -> str: + return f""" +{{name = {self.name}, \ +app_id = {self.app_id}, \ +top_line = {self.top_line}, \ +bottom_line = {self.bottom_line}, \ +small_icon = {self.small_icon}, \ +time = {self.time}}}""" diff --git a/fetch_cord/Fetch.py b/fetch_cord/Fetch.py new file mode 100644 index 0000000..c3214d1 --- /dev/null +++ b/fetch_cord/Fetch.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python3 + +import platform +import json +import re +from pathlib import Path +from typing import Dict + +from fetch_cord import resources +from fetch_cord.native import native as native_module +from fetch_cord.Tools import exec_bash, exec_ps1 +from fetch_cord.get_resources import get_default_config + + +def get_infos(name: str): + module_path = Path(resources.__file__).parent + file_path = module_path / f"{name}.json" + with file_path.open() as f: + return json.load(f) + + +def get_component_id(search: str, id_list: dict) -> str: + for id, patterns in id_list.items(): + if any(re.search(pattern, search) for pattern in patterns): + return id + + print(f"Warning: No match found for '{search}' in the provided patterns: {id_list}") + for id, patterns in id_list.items(): + if "unknown" in patterns: + return id + + return "unknown" + + +class Fetch: + scripts: Dict + + def __init__(self, scripts: Dict): + self.scripts = scripts + + def run_script(self, script: str) -> str: + # TODO fastfetch config handling + # if "neofetch" in script: + # script.replace("neofetch", f"neofetch --config {get_default_config()}") + + if platform.system() == "Windows": + return exec_ps1(script) + else: + return exec_bash(script) + + def fetch(self, component_class: str) -> str: + result = ( + native_module.fetch(component_class) + if component_class not in self.scripts + else self.run_script(self.scripts[component_class]) + ) + + if result is None: + return f"Error: Component {component_class} not found" + + if result != "": + return result.lstrip().split("\n")[0] + + return "Not Found" diff --git a/fetch_cord/Logger.py b/fetch_cord/Logger.py index e39fac3..d49bb30 100755 --- a/fetch_cord/Logger.py +++ b/fetch_cord/Logger.py @@ -2,6 +2,7 @@ import logging from logging.handlers import TimedRotatingFileHandler + class Logger(logging.Logger): FORMATTER = logging.Formatter( "%(asctime)s - %(name)s - %(levelname)s - %(message)s" @@ -34,4 +35,4 @@ def __init__(self, file: str, name: str, level: int = logging.INFO): self.addHandler(self.console_handler) self.addHandler(self.file_handler) - self.propagate = False \ No newline at end of file + self.propagate = False diff --git a/fetch_cord/Tools.py b/fetch_cord/Tools.py new file mode 100644 index 0000000..6bcfb73 --- /dev/null +++ b/fetch_cord/Tools.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python3 + +# trunk-ignore(bandit/B404) +import subprocess +from importlib import resources +from pathlib import Path +from typing import List + + +def run_command(command: List[str], shell: bool = False) -> str: + return subprocess.run( + command, + encoding="utf-8", + stdout=subprocess.PIPE, + # trunk-ignore(bandit/B602) + shell=shell, + ).stdout + + +def exec_bash(command: str) -> str: + return subprocess.run( + [command], + encoding="utf-8", + stdout=subprocess.PIPE, + # trunk-ignore(bandit/B602) + shell=True, + ).stdout.strip() + + +def exec_ps1(command: str) -> str: + # trunk-ignore(bandit/B603) + # trunk-ignore(bandit/B607) + return subprocess.run( + ["powershell", command], encoding="utf-8", stdout=subprocess.PIPE + ).stdout.strip() + + +def get_resource_path(package, resource: str) -> Path: + with resources.path(package, resource) as path: + return path + + +class BashError(Exception): + pass diff --git a/fetch_cord/__init__.py b/fetch_cord/__init__.py index d91f62f..ea9d694 100755 --- a/fetch_cord/__init__.py +++ b/fetch_cord/__init__.py @@ -1 +1 @@ -VERSION = "2.7.6" +VERSION = "3.0.0" diff --git a/fetch_cord/__main__.py b/fetch_cord/__main__.py index 0dd4bcc..e7040b6 100755 --- a/fetch_cord/__main__.py +++ b/fetch_cord/__main__.py @@ -1,20 +1,27 @@ # from __future__ import annotations -from typing import Dict -import sys, os +import platform +import sys +import os -from .run_rpc import Run_rpc -from .cycles import cycle0, cycle1, cycle2, cycle3, runmac, windows, pause -from .computer.Computer import Computer -from .args import parse_args -from .debugger import run_rpc_debug -from .update import update -from . import __init__ as __init__ -from .resources import systemd_service +from signal import SIGINT, SIGTERM, signal +from threading import Event +from fetch_cord.Config import Config +from fetch_cord.Cycle import Cycle +from fetch_cord.Fetch import Fetch, get_infos, get_component_id +from fetch_cord.update import update +from fetch_cord.resources import systemd_service +from fetch_cord.args import parse_args +from . import VERSION -def main(): - args = parse_args() +args = parse_args() +__all__ = [args] + +args = parse_args() + +def handle_args() -> None: + """Handle the arguments passed to the program.""" if args.update: update() @@ -34,10 +41,10 @@ def main(): if args.status: systemd_service.status() if args.version: - print("FetchCord version:", __init__.VERSION) + print("FetchCord version:", VERSION) sys.exit(0) if args.time: - if int(args.time) < 15: + if float(args.time) < 15: print("ERROR: Invalid time set, must be > 15 seconds, cannot continue.") sys.exit(1) else: @@ -48,74 +55,82 @@ def main(): except AttributeError: pass - computer: Computer = Computer() - - if ( - not computer.neofetchwin - and computer.host == "Host: N/A" - and args.nodistro - and args.noshell - and args.nohardware - ): - print("ERROR: no hostline is available!") - sys.exit(1) - # printing info with debug switch - if args.debug: - run_rpc_debug(computer) - - run: Run_rpc = Run_rpc() - - if computer.neofetchwin: - # wandowz - loops: Dict = {} - loops_indexes: Dict = {} - - if not args.nodistro: - loops["windows"] = (computer.osinfoid, windows) - loops_indexes[len(loops_indexes)] = "windows" - if not args.nohardware: - loops["cycle1"] = (computer.cpuid, cycle1) - loops_indexes[len(loops_indexes)] = "cycle1" - - run.set_loop( - loops, - loops_indexes, - computer.updateMap, - int(args.poll_rate) if args.poll_rate else 3, - ) - run.run_loop(computer) - else: - # loonix - loops: Dict = {} - loops_indexes: Dict = {} - - if not args.nodistro and computer.os != "macos": - loops["cycle0"] = (computer.osinfoid, cycle0) - loops_indexes[len(loops_indexes)] = "cycle0" - if computer.os == "macos": - loops["runmac"] = ("740822755376758944", runmac) - loops_indexes[len(loops_indexes)] = "runmac" - if not args.nohardware: - loops["cycle1"] = (computer.cpuid, cycle1) - loops_indexes[len(loops_indexes)] = "cycle1" - if not args.noshell: - loops["cycle2"] = (computer.terminalid, cycle2) - loops_indexes[len(loops_indexes)] = "cycle2" - if not args.nohost and computer.os != "macos": - loops["cycle3"] = (computer.hostappid, cycle3) - loops_indexes[len(loops_indexes)] = "cycle3" - if args.pause_cycle: - loops["pause"] = ("", pause) - loops_indexes[len(loops_indexes)] = "pause" - - run.set_loop( - loops, - loops_indexes, - computer.updateMap, - int(args.poll_rate) if args.poll_rate else 3, - ) - run.run_loop(computer) + +def main(): + handle_args() + + # Get the ids for the components + fetchcord_ids = { + "cpu": get_infos("cpus"), + "gpu": get_infos("gpus"), + "os": get_infos("os"), + "terminal": get_infos("terminal"), + "shell": get_infos("shell"), + "motherboard": get_infos("motherboards"), + "system_type": get_infos("system_types"), + } + + # Stop event for the loop + stop_event = Event() + + # Load config + config = Config() + config["commands"] = Config("fetchcord_cmds.yml")["commands"] + # Load cycles + cycles = [Cycle(cycle, stop_event) for cycle in config["cycles"]] + + os_type = platform.system() + scripts = { + component_type: value[os_type] + for component_type, value in config["commands"].items() + if os_type in value + } + + fetch = Fetch(scripts) + + # Handle Ctrl+C and SIGTERM + signal(SIGINT, lambda s, f: stop_event.set()) + signal(SIGTERM, lambda s, f: stop_event.set()) + + # Main loop + while not stop_event.is_set(): + # Loop through the cycles defined in the config + for cycle in cycles: + if stop_event.is_set(): + break + + app = fetch.fetch(cycle.app_id) + bottom = fetch.fetch(cycle.bottom_line) + top = fetch.fetch(cycle.top_line) + icon = fetch.fetch(cycle.small_icon) + + client_id = get_component_id(app.lower(), fetchcord_ids[cycle.app_id]) + + icon_id = get_component_id(icon, fetchcord_ids[cycle.small_icon]) + + print( + f"""client_id: {client_id} \ +app: {app} \ +bottom: {bottom} \ +top: {top} \ +icon: {icon} \ +icon_id: {icon_id}""" + ) + + if cycle.rpc is None: + cycle.setup(client_id) + + try: + cycle.try_connect() + except ConnectionResetError: + cycle.try_connect() + + cycle.update(client_id, app, bottom, top, icon, icon_id) + + stop_event.wait(0.05) + + print("Closing connection.") if __name__ == "__main__": - main() \ No newline at end of file + main() diff --git a/fetch_cord/args.py b/fetch_cord/args.py index a9425f7..01d37bb 100755 --- a/fetch_cord/args.py +++ b/fetch_cord/args.py @@ -1,10 +1,7 @@ -# from __future__ import annotations - import argparse def parse_args(): - parser = argparse.ArgumentParser( description="Fetch Cord\n" "https://github.com/MrPotatoBobx/FetchCord" ) @@ -21,7 +18,7 @@ def parse_args(): parser.add_argument( "--noconfig", action="store_true", - help="Disable neofetch custom config. Enable if you have an incompatible custom configuration.", + help="Disable fastfetch custom config. Enable if you have an incompatible custom configuration.", ) parser.add_argument( "--time", @@ -40,7 +37,7 @@ def parse_args(): "--termfont", metavar="TERMFONT", action="store", - help="Set custom Terminal Font (useful if neofetch can't get it).", + help="Set custom Terminal Font (useful if fastfetch can't get it).", ) parser.add_argument( "--install", @@ -115,7 +112,7 @@ def parse_args(): "--config-path", "-c", action="store", - help="Specify custom neofetch config path.", + help="Specify custom fastfetch config path.", ) parser.add_argument( "--fetchcord-config-path", diff --git a/fetch_cord/computer/Computer.py b/fetch_cord/computer/Computer.py deleted file mode 100755 index 466036a..0000000 --- a/fetch_cord/computer/Computer.py +++ /dev/null @@ -1,569 +0,0 @@ -# from __future__ import annotations - -import logging -from sys import platform, exit -import sys -from typing import Callable, Dict, List, Tuple -import psutil, os - -from ..run_command import exec_bash, run_command -from ..args import parse_args -from ..Logger import Logger -from .flatpak import enableFlatpak -from .resources import get_infos, get_default_config -from .cpu.get_cpu import get_cpu -from .cpu.Cpu_interface import Cpu_interface -from .gpu.get_gpu import get_gpu -from .gpu.Gpu_interface import GpuType, get_gpuid - -args = parse_args() - -logger = Logger( - "fetchcord_computer.log", - "fetchcord_computer", - logging.DEBUG if args.debug else logging.INFO, -) - - -class Computer: - parseMap: Dict[str, Callable] - componentMap: Dict[str, List] = {} - idsMap: Dict[str, Dict] - - os: str - neofetchwin: bool = False - neofetch: bool = False - values: str - laptop: bool = False - uptime: float - - @property - def memory(self) -> str: - return self.get_component_line("Memory:") - - @property - def osinfo(self) -> str: - return self.get_component_line("OS:") - - @property - def osinfoid(self) -> str: - component = self.get_component_line("OS:") - component = (component.split()[0] + component.split()[1]).lower() - component_list = self.idsMap[self.idsMap["map"]["OS:"]] - - for comp, id in component_list.items(): - if component.lower().find(comp.lower()) >= 0: - return id - - print( - "Unknown {}, contact us on github to resolve this.".format( - self.idsMap["map"]["OS:"] - ) - ) - - return component_list["unknown"] - - @property - def motherboard(self) -> str: - return self.get_component_line("Motherboard:") - - @property - def motherboardid(self) -> str: - return self.get_component_idkey("Motherboard:") - - @property - def host(self) -> str: - return self.get_component_line("Host:") - - @property - def hostid(self) -> str: - hostsplit = self.host.split() - host_list: Dict[str, str] = self.idsMap[self.idsMap["map"]["Host:"]] - - for line in hostsplit: - if line in host_list: - return line - - # try to get MacBook hostid - hostid = [] - hostjoin = " ".join(self.host) - for numsplit in range(len(hostjoin)): - if not hostjoin[numsplit].isdigit(): - hostid.append(hostjoin[numsplit]) - hostid = "".join(hostid) - hostid = hostid.split()[1] - - if hostid in host_list: - return host_list[hostid] - else: - return host_list["unknown"] - - @property - def hostappid(self) -> str: - return self.get_component_id("Host:") - - @property - def cpu(self) -> str: - key = "CPU:" - cpus: List[Cpu_interface] = self.get_component(key) - temp = [] - for cpu in cpus: - temp.append(cpu.info) - - return "\n".join(temp) if len(cpus) > 0 else "{} N/A".format(key) - - @property - def cpuid(self) -> str: - temp: List[Cpu_interface] = self.get_component("CPU:") - - if len(temp) == 0: - return self.idsMap[self.idsMap["map"]["CPU:"]]["unknown"] - else: - return temp[0].get_id(self.idsMap[self.idsMap["map"]["CPU:"]]) - - @property - def gpu(self) -> str: - key = "GPU:" - gpus: List[GpuType] = self.get_component(key) - temp = [] - for gpu in gpus: - if gpu.vendor == "amd" and self.os == "linux": - temp.append(gpu.get_amdgpurender(gpus, self.laptop).rstrip().lstrip()) - else: - temp.append(gpu.model.lstrip().rstrip()) - - return "\n".join(temp) if len(gpus) > 0 else "{} N/A".format(key) - - @property - def gpuid(self) -> str: - return get_gpuid( - self.idsMap[self.idsMap["map"]["GPU:"]], self.get_component("GPU:") - ) - - @property - def disks(self) -> str: - return self.get_component_line("Disk") - - @property - def resolution(self) -> str: - return self.get_component_line("Resolution:") - - @property - def theme(self) -> str: - return self.get_component_line("Theme:") - - @property - def kernel(self) -> str: - return self.get_component_line("Kernel:") - - @property - def packages(self) -> str: - return self.get_component_line("Packages:") - - @property - def shell(self) -> str: - return self.get_component_line("Shell:") - - @property - def shellid(self) -> str: - return self.get_component_id("Shell:") - - @property - def terminal(self) -> str: - return self.get_component_line("Terminal:") - - @property - def terminalid(self) -> str: - return self.get_component_id("Terminal:") - - @property - def wm(self) -> str: - return self.get_component_line("WM:") - - @property - def wmid(self) -> str: - return self.get_component_line("WM:").split()[0] - - @property - def font(self) -> str: - return self.get_component_line("Font:") - - @property - def de(self) -> str: - return self.get_component_line("DE:") - - @property - def deid(self) -> str: - value = self.get_component_line("DE:").split()[0] - - return "n/a" if value == "DE:" else value - - @property - def dewmid(self) -> str: - de = self.get_component_line("DE:") - - return "\n".join( - ["" if de == "{} N/A".format("DE:") else de, self.get_component_line("WM:")] - ) - - @property - def desktopid(self) -> str: - deid = self.deid.lower() - wmid = self.wmid.lower() - - if deid == "unity": - if wmid == "compiz": - return "unity" - else: - return wmid - - if deid != "n/a" and deid in self.idsMap[self.idsMap["map"]["DE:"]]: - return deid - elif deid == "n/a" and wmid in self.idsMap[self.idsMap["map"]["WM:"]]: - return wmid - else: - print("Unknown DE/WM, contact us on github to resolve this.") - return "unknown" - - @property - def battery(self) -> str: - if self.laptop: - return self.get_component_line("Battery") - else: - return "{} N/A".format("Battery") - - @property - def lapordesk(self) -> str: - if self.laptop and self.os != "macos": - return "laptop" - else: - return "desktop" - - @property - def version(self) -> str: - return os.popen("sw_vers -productVersion").read() - - @property - def product(self) -> str: - return os.popen("sysctl -n hw.model").read() - - @property - def devicetype(self) -> str: - if self.product[0:7] == "MacBook": - return "laptop" - else: - return "desktop" - - @property - def bigicon(self) -> str: - try: - return self.idsMap[self.idsMap["map"]["Version:"]][self.version[0:5]] - except KeyError: - print("Unsupported MacOS version") - return "bigslurp" - - def __init__(self): - super().__init__() - - self.parseMap = { - "CPU:": get_cpu, - "GPU:": get_gpu, - "Disk": self.get_disk, - "Memory:": self.get_memory, - "OS:": self.get, - "Motherboard:": self.get, - "Host:": self.get, - "Resolution:": self.get, - "Theme:": self.get, - "Kernel:": self.get, - "Packages:": self.get, - "Shell:": self.get, - "Terminal:": self.get, - "Font:": self.get, - "DE:": self.get, - "WM:": self.get, - "Battery": self.get_battery, - } - - self.idsMap = get_infos() - self.uptime = psutil.boot_time() - - self.detect_os() - self.detect_laptop() - - self.fetch_values() - - def fetch_values(self): - self.neofetchwin, self.neofetch, self.values = self.detect_neofetch() - - self.neofetch_parser(self.values) - - if not bool(self.componentMap): - args.config_path = "" - args.noconfig = False - - self.neofetchwin, self.neofetch, self.values = self.detect_neofetch() - self.neofetch_parser(self.values) - - terminallist = self.idsMap[self.idsMap["map"]["Terminal:"]] - if args.terminal and args.terminal.lower() in terminallist: - self.componentMap["Terminal:"] = [args.terminal.lower()] - elif args.terminal and args.terminal.lower() not in terminallist: - print( - "\nInvalid terminal, only %s are supported.\n" - "Please make a github issue if you would like to have your terminal added.\n" - "https://github.com/MrPotatoBobx/FetchCord" % terminallist - ) - sys.exit(1) - - if self.get_component("Font:", True) and args.termfont: - print( - "Custom terminal font not set because a terminal font already exists, %s" - % self.font - ) - elif not self.get_component("Font:", True) and args.termfont: - self.componentMap["Font:"] = [args.termfont] - - def updateMap(self): - """ - Clear the components values and fetch new ones - """ - self.clearMap() - self.neofetchwin, self.neofetch, self.values = self.detect_neofetch() - self.neofetch_parser(self.values) - - def clearMap(self): - """ - Clear the components values - """ - for key in self.componentMap.keys(): - del self.componentMap[key][:] - - def neofetch_parser(self, values: str): - if args.debug: - print(values) - lines = values.split("\n") - for i in range(len(lines)): - line = lines[i] - for key, detectedFunction in [ - (key, value) for key, value in self.parseMap.items() if key in line - ]: - if key not in self.componentMap: - self.componentMap[key] = [] - detectedFunction( - self.os, self.componentMap[key], line.rstrip("\n"), key - ) - - def detect_os(self) -> str: - if platform == "linux" or platform == "linux2": - self.os = "linux" - elif platform == "darwin": - self.os = "macos" - elif platform == "win32": - self.os = "windows" - else: - raise Exception("Not a supported OS !") - - return self.os - - def detect_laptop(self) -> bool: - if self.os != "linux": - self.laptop = False - else: - for i in os.listdir("/sys/class/power_supply"): - if i.startswith("BAT"): - self.laptop = True - break - - return self.laptop - - def detect_neofetch(self): - neofetchwin = False - neofetch = False - values = None - - if self.os == "windows": - try: - values = run_command(["neofetch", "--noart"]) - except Exception: - pass - else: - neofetchwin = True - elif not neofetchwin: - if self.os == "linux": - enableFlatpak() - - default_config = get_default_config() - - try: - if self.os == "windows": - values = run_command( - [ - "neofetch", - "--config {}".format( - "none" - if args.noconfig - else ( - args.config_path - if args.config_path - else (default_config) - ) - ), - "--stdout", - ], - shell=(self.os == "windows"), - ) - else: - values = exec_bash( - "neofetch --config {} --stdout".format( - "none" - if args.noconfig - else ( - args.config_path - if args.config_path - else (default_config) - ) - ) - ) - if args.nfco: - with open(args.nfco) as f: - values = "\n".join(f.readlines()) - - except Exception: - print( - "ERROR: Neofetch not found, please install it or check installation and that neofetch is in PATH." - ) - exit(1) - else: - neofetch = True - - return (neofetchwin, neofetch, values) - - def get_battery(self, os: str, line: List, value: str, key: str): - """ - Append the Battery info from given neofetch line - - Parameters - ---------- - value : str - Neofetch extracted line - """ - - line.append(value[value.find(key) + len(key) + 2 :]) - - def get_disk(self, os: str, line: List, value: str, key: str): - """ - Append the Disk info from the given neofetch line to the Disk list - - Parameters - ---------- - value : str - Neofetch extracted line - """ - - line.append(value[value.find(key) + len(key) + 2 :]) - - def get_memory(self, os: str, line: List, value: str, key: str): - """ - Get the memory info from the given neofetch line - - Parameters - ---------- - value : str - Neofetch extracted line - """ - - if args.memtype == "gb": - memgb = value.split() - used = float(memgb[1].replace("MiB", "")) - total = float(memgb[3].replace("MiB", "")) - - line.append( - " ".join( - [ - str(round(used / 1024, 2)), - "GiB /", - str(round(total / 1024, 2)), - "GiB", - ] - ) - ) - else: - line.append(value[value.find(key) + len(key) + 1 :]) - - def get(self, os: str, line: List, value: str, key: str, valueOffset: int = 1): - """ - Get the info from the given neofetch line - - Parameters - ---------- - os: str - Detected OS ("windows", "linux" or "macos") - line: List - List who will contains the values - value : str - Neofetch extracted line - key : str - Key for the dict - valueOffset: int - Offset for extracting the value without the key (default : 1) - """ - - line.append(value[value.find(key) + len(key) + valueOffset :]) - - def get_component(self, key: str, quiet: bool = False): - """ - Get component info from map - - Args: - key (str): component key in map - """ - try: - return self.componentMap[key] - except KeyError as err: - if quiet: - print("[KeyError]: {}".format(err), end="") - - return [] - - def get_component_line(self, key: str) -> str: - try: - values = self.componentMap[key] - return "\n".join(values) if len(values) > 0 else "{} N/A".format(key) - except KeyError as err: - print("[KeyError]: ", end="") - print(err) - - return "{} N/A".format(key) - - def get_component_id(self, key: str) -> str: - component = self.get_component_line(key).lower() - component_list = self.idsMap[self.idsMap["map"][key]] - - for comp, id in component_list.items(): - if component.find(comp.lower()) >= 0: - return id - - print( - "Unknown {}, contact us on github to resolve this.".format( - self.idsMap["map"][key] - ) - ) - - return component_list["unknown"] - - def get_component_idkey(self, key: str) -> str: - component = self.get_component_line(key).lower() - component_list = self.idsMap[self.idsMap["map"][key]] - - for comp, _ in component_list.items(): - if component.find(comp.lower()) >= 0: - return comp - - print( - "Unknown {}, contact us on github to resolve this.".format( - self.idsMap["map"][key] - ) - ) - - return component_list["unknown"] diff --git a/fetch_cord/computer/Peripheral_interface.py b/fetch_cord/computer/Peripheral_interface.py deleted file mode 100755 index 987a982..0000000 --- a/fetch_cord/computer/Peripheral_interface.py +++ /dev/null @@ -1,11 +0,0 @@ -#from __future__ import annotations - -from abc import ABCMeta - - -class Peripherical_interface(metaclass=ABCMeta): - os: str - - def __init__(self, os): - super().__init__() - self.os = os \ No newline at end of file diff --git a/fetch_cord/computer/cpu/Cpu_amd.py b/fetch_cord/computer/cpu/Cpu_amd.py deleted file mode 100755 index 9b768fc..0000000 --- a/fetch_cord/computer/cpu/Cpu_amd.py +++ /dev/null @@ -1,53 +0,0 @@ -# from __future__ import annotations - -import os -from sys import platform - -if os.name != "nt" and platform != "darwin": - from psutil import sensors_temperatures -from .Cpu_interface import Cpu_interface - -CPU_VENDOR = "amd" - - -class Cpu_amd(Cpu_interface): - def __init__(self, os, model): - super().__init__(os, CPU_VENDOR, model) - - @Cpu_interface.model.setter - def model(self, value: str): - self.info = " ".join(value.split()[1:]) - self._model = " ".join([value.split()[2], value.split()[3]]) - - if self._model.find("APU") != -1 or ( - self._model.find("RADEON") != -1 and self._model.lower().find("ryzen") == -1 - ): - self._model = f"{self._model.split('-')[0]} APU" - - def get_temp(self) -> float: - if self.os == "windows": - raise NotImplementedError( - "Temperature report for AMD CPU's is not supported on Windows yet." - ) - elif self.os == "macos": - raise NotImplementedError( - "Temperature report for AMD CPU's is not supported on MacOS yet." - ) - elif ( - self.os == "linux" # and os.name != "nt" linux only - ): # os.name comparaison not needed, its just for the linter - sensors = sensors_temperatures() - if "k10temp" in sensors: - temps = sensors["k10temp"] - if len(temps) == 1: - return temps.current - else: - for temp in temps: - if temp.label == "Tdie": - return temp.current - - raise Exception("No valid temperature value found.") - - raise Exception("No valid sensor found.") - else: - raise NotImplementedError("Unknown OS, no CPU temperature report.") diff --git a/fetch_cord/computer/cpu/Cpu_intel.py b/fetch_cord/computer/cpu/Cpu_intel.py deleted file mode 100755 index 427f201..0000000 --- a/fetch_cord/computer/cpu/Cpu_intel.py +++ /dev/null @@ -1,48 +0,0 @@ -#from __future__ import annotations - -from .Cpu_interface import Cpu_interface -import re - -CPU_VENDOR = "intel" - - -class Cpu_intel(Cpu_interface): - def __init__(self, os, model): - super().__init__(os, CPU_VENDOR, model) - - @Cpu_interface.model.setter - def model(self, value: str): - self.info = " ".join(value.split()[1:]) - if value.split()[1].replace("Intel(R)", "Intel") == "Pentium": - self._model = value.split()[1] - else: - # Remove "CPU: ", "(R)" and "(TM)" - self._model = " ".join( - re.sub(r"\((.+)\)", "", value.replace("-", " ")).split()[1:] - ) - - # Core 2 Duo, Core 2 Quad - if self._model.find("Intel Core") != -1: - self._model = " ".join(self._model.split()[:4]) - else: - self._model = " ".join(self._model.split()[:2]) - - if self._model == "Intel Core": - self._model = value.split()[1:5] - self._model = " ".join(self._model) - - def get_temp(self): - if self.os == "windows": - raise NotImplementedError( - "Temperature report for Intel CPU's is not supported on Windows yet." - ) - elif self.os == "macos": - raise NotImplementedError( - "Temperature report for Intel CPU's is not supported on MacOS yet." - ) - elif self.os == "linux": - raise NotImplementedError( - "Temperature report for Intel CPU's is not supported on Linux yet." - ) - else: - raise NotImplementedError("Unkown OS, no CPU temperature report.") diff --git a/fetch_cord/computer/cpu/Cpu_interface.py b/fetch_cord/computer/cpu/Cpu_interface.py deleted file mode 100755 index ee53949..0000000 --- a/fetch_cord/computer/cpu/Cpu_interface.py +++ /dev/null @@ -1,54 +0,0 @@ -#from __future__ import annotations - -from abc import ABCMeta, abstractmethod -from typing import Dict - -from ..Peripheral_interface import Peripherical_interface - - -class Cpu_interface(Peripherical_interface, metaclass=ABCMeta): - vendor: str - _model: str - info: str - - @property - def model(self) -> str: - return self._model - - @model.setter - @abstractmethod - def model(self, value: str): - raise NotImplementedError - - @property - def temp(self) -> float: - try: - self._temp = self.get_temp() - except NotImplementedError as e: - try: - raise e - finally: - e = None - del e - - else: - return self._temp - - @temp.setter - def temp(self, value: float): - self._temp = value - - def __init__(self, os, vendor, model): - super().__init__(os) - self.vendor = vendor - self.model = model - - @abstractmethod - def get_temp(self) -> float: - raise NotImplementedError - - def get_id(self, cpu_list: Dict[str, str]) -> str: - if self.model.lower() in cpu_list[self.vendor]: - return cpu_list[self.vendor][self.model.lower()] - else: - return cpu_list["unknown"] diff --git a/fetch_cord/computer/cpu/__init__.py b/fetch_cord/computer/cpu/__init__.py deleted file mode 100755 index e69de29..0000000 diff --git a/fetch_cord/computer/cpu/get_cpu.py b/fetch_cord/computer/cpu/get_cpu.py deleted file mode 100755 index 85b2ec3..0000000 --- a/fetch_cord/computer/cpu/get_cpu.py +++ /dev/null @@ -1,30 +0,0 @@ -#from __future__ import annotations - -from typing import List - -from .Cpu_amd import Cpu_amd -from .Cpu_intel import Cpu_intel - - -def get_cpu(os: str, line: List, value: str, key: str): - """ - Append the CPU info from the given neofetch line to the CPU list - - Parameters - ---------- - os : - OS type - line : List - Component line - value : str - Neofetch extracted line - key : str - Component key - """ - - vendor = value.replace(key, "").lstrip("").replace("Intel(R)", "Intel") - - if vendor.find("Intel") != -1 or vendor.find("Pentium") != -1: - line.append(Cpu_intel(os, value)) - elif vendor.find("AMD") != -1: - line.append(Cpu_amd(os, value)) \ No newline at end of file diff --git a/fetch_cord/computer/gpu/Gpu_amd.py b/fetch_cord/computer/gpu/Gpu_amd.py deleted file mode 100755 index c6be835..0000000 --- a/fetch_cord/computer/gpu/Gpu_amd.py +++ /dev/null @@ -1,55 +0,0 @@ -# from __future__ import annotations -from fetch_cord.run_command import BashError, exec_bash -from typing import List -import sys - -from .Gpu_interface import Gpu_interface, GpuType - -GPU_VENDOR = "amd" - - -class Gpu_amd(Gpu_interface): - def __init__(self, os, model): - super().__init__(os, GPU_VENDOR, model) - - @Gpu_interface.model.setter - def model(self, value: str): - self._model = value - - def get_temp(self): - if self.os == "windows": - raise NotImplementedError( - "Temperature report for AMD GPU's is not supported on Windows yet." - ) - elif self.os == "macos": - raise NotImplementedError( - "Temperature report for AMD GPU's is not supported on MacOS yet." - ) - elif self.os == "linux": - raise NotImplementedError( - "Temperature report for AMD GPU's is not supported on Linux yet." - ) - else: - raise NotImplementedError("Unknown OS, no GPU temperature report.") - - def get_amdgpurender(self, gpu_list: List[GpuType], laptop: bool) -> str: - try: - for i in range(len(gpu_list)): - # assume DRI_PRIME=0 is the intel GPU - if laptop and "intel" == gpu_list[i].vendor.lower(): - i += 1 - if ( - laptop - and "amd" == gpu_list[i].vendor.lower() - and gpu_list[i].model != self.model - ): - i += 1 - - env_prime = "DRI_PRIME=%s" % i - return exec_bash( - "%s glxinfo | grep \"OpenGL renderer string:\" |sed 's/^.*: //;s/[(][^)]*[)]//g'" - % env_prime - ) - except BashError as e: - print("ERROR: Could not run glxinfo [%s]" % str(e)) - sys.exit(1) \ No newline at end of file diff --git a/fetch_cord/computer/gpu/Gpu_intel.py b/fetch_cord/computer/gpu/Gpu_intel.py deleted file mode 100755 index 4b56a6f..0000000 --- a/fetch_cord/computer/gpu/Gpu_intel.py +++ /dev/null @@ -1,34 +0,0 @@ -# from __future__ import annotations -from .Gpu_interface import Gpu_interface - -GPU_VENDOR = "intel" - - -class Gpu_intel(Gpu_interface): - def __init__(self, os, model): - super().__init__(os, GPU_VENDOR, model) - - @Gpu_interface.model.setter - def model(self, value: str): - self._model = value - - @Gpu_interface.vendor.setter - def vendor(self, value: str): - self._vendor = value.replace(f"{GPU_VENDOR}(R)", f"{GPU_VENDOR}") - - - def get_temp(self): - if self.os == "windows": - raise NotImplementedError( - "Temperature report for Intel GPU's is not supported on Windows yet." - ) - elif self.os == "macos": - raise NotImplementedError( - "Temperature report for Intel GPU's is not supported on MacOS yet." - ) - elif self.os == "linux": - raise NotImplementedError( - "Temperature report for Intel GPU's is not supported on Linux yet." - ) - else: - raise NotImplementedError("Unknown OS, no GPU temperature report.") diff --git a/fetch_cord/computer/gpu/Gpu_interface.py b/fetch_cord/computer/gpu/Gpu_interface.py deleted file mode 100755 index 5c436b9..0000000 --- a/fetch_cord/computer/gpu/Gpu_interface.py +++ /dev/null @@ -1,72 +0,0 @@ -# from __future__ import annotations -from abc import ABCMeta, abstractmethod -from typing import List, TypeVar, Dict - -from ..Peripheral_interface import Peripherical_interface - - -class Gpu_interface(Peripherical_interface, metaclass=ABCMeta): - _vendor: str - _model: str - - @property - def vendor(self) -> str: - return self._vendor - - @vendor.setter - def vendor(self, value: str): - self._vendor = value - - @property - def model(self) -> str: - return self._model - - @model.setter - @abstractmethod - def model(self, value: str): - raise NotImplementedError - - @property - def temp(self) -> float: - try: - self._temp = self.get_temp() - except NotImplementedError as e: - try: - raise e - finally: - e = None - del e - - else: - return self._temp - - @temp.setter - def temp(self, value: float): - self._temp = value - - def __init__(self, os, vendor, model): - super().__init__(os) - self.vendor = vendor - self.model = model - - @abstractmethod - def get_temp(self) -> float: - raise NotImplementedError - - -GpuType = TypeVar("GpuType", bound="Gpu_interface") - - -def get_gpuid(gpu_ids: Dict[str, str], gpus: List[GpuType]): - vendors = [] - for i in range(len(gpus)): - if gpus[i].vendor not in vendors: - vendors.append(gpus[i].vendor) - - gpuvendor = "".join(vendors).lower() - - if gpuvendor in gpu_ids: - return gpu_ids[gpuvendor] - else: - print("Unknown GPU, contact us on github to resolve this.") - return "unknown" diff --git a/fetch_cord/computer/gpu/Gpu_nvidia.py b/fetch_cord/computer/gpu/Gpu_nvidia.py deleted file mode 100755 index f0c3e4c..0000000 --- a/fetch_cord/computer/gpu/Gpu_nvidia.py +++ /dev/null @@ -1,44 +0,0 @@ -# from __future__ import annotations -from fetch_cord.run_command import BashError, exec_bash -from .Gpu_interface import Gpu_interface - -GPU_VENDOR = "nvidia" - - -class Gpu_nvidia(Gpu_interface): - primeoffload: bool - - def __init__(self, os, model): - super().__init__(os, GPU_VENDOR, model) - - @Gpu_interface.model.setter - def model(self, value: str): - self._model = value - - def get_temp(self): - if self.os == "windows": - raise NotImplementedError( - "Temperature report for Nvidia GPU's is not supported on Windows yet." - ) - elif self.os == "macos": - raise NotImplementedError( - "Temperature report for Nvidia GPU's is not supported on MacOS yet." - ) - elif self.os == "linux": - try: - return exec_bash( - "nvidia-smi -q | awk '/GPU Current Temp/{print $5}' | sed 's/^/[/;s/$/°C]/'" - ) - except BashError: - pass - else: - raise NotImplementedError("Unknown OS, no GPU temperature report.") - - def check_primeoffload(self): - # only show the GPU in use with optimus, show both if prime render offload - self.primeoffload = False - try: - self.primeoffload = exec_bash('xrandr --listproviders | grep -o "NVIDIA-0"') - return True - except BashError: - return False \ No newline at end of file diff --git a/fetch_cord/computer/gpu/__init__.py b/fetch_cord/computer/gpu/__init__.py deleted file mode 100755 index e69de29..0000000 diff --git a/fetch_cord/computer/gpu/get_gpu.py b/fetch_cord/computer/gpu/get_gpu.py deleted file mode 100755 index 59c4328..0000000 --- a/fetch_cord/computer/gpu/get_gpu.py +++ /dev/null @@ -1,37 +0,0 @@ -# from __future__ import annotations -from typing import List - -from .Gpu_amd import Gpu_amd -from .Gpu_nvidia import Gpu_nvidia -from .Gpu_intel import Gpu_intel - - -def get_gpu(os: str, line: List, value: str, key: str): - """ - Append the GPU info from the given neofetch line to the GPU list - - Parameters - ---------- - os : - OS type - line : List - Component line - value : str - Neofetch extracted line - key : str - Component key - """ - - value = value.replace(key, "").lstrip() - splitValue = value.split() - - for v in splitValue: - if v.upper() in ["AMD", "RADEON"]: - line.append(Gpu_amd(os, value)) - return - elif v.upper() in ["NVIDIA", "GEFORCE"]: - line.append(Gpu_nvidia(os, value)) - return - elif v.upper() in ["INTEL", "INTEL(R)"]: - line.append(Gpu_intel(os, value)) - return \ No newline at end of file diff --git a/fetch_cord/config.py b/fetch_cord/config.py deleted file mode 100755 index 2173992..0000000 --- a/fetch_cord/config.py +++ /dev/null @@ -1,227 +0,0 @@ -#from __future__ import annotations - - -try: - import importlib.resources as pkg_resources -except ImportError: - # Try backported to PY<37 `importlib_resources`. - import importlib_resources as pkg_resources -import os, copy, json, configparser - -from . import resources as fc_resources -from .args import parse_args - - -args = parse_args() - - -class ConfigError(Exception): - pass - - -def load_config(): - default_config = configparser.ConfigParser() - with pkg_resources.path(fc_resources, "fetch_cord.conf") as path: - default_config.read_file(open(path)) - default_config.read( - ["/etc/fetch_cord.conf", os.path.expanduser("~/fetch_cord.conf")] - ) - if args.fetchcord_config_path != None: - default_config.read([args.fetchcord_config_path]) - for item in default_config.items(): - print(item) - - default_config = _parsed_config_to_dict(default_config) - _validate_config(default_config) - - return default_config - - -# def load_config(): -# base_config = configparser.ConfigParser() -# base_config.read(["/etc/fetch_cord.conf"]) -# base_config = _parsed_config_to_dict(base_config) -# _validate_config(base_config) - - -# # try: -# user_config = configparser.ConfigParser() -# user_config.read("/etc/fetch_cord.conf") -# user_config = _parsed_config_to_dict(user_config) -# # except configparser.ParsingError as e: -# # print( -# # "Error parsing config file %s. Falling back to default config %s. Error is : %s", -# # envs.USER_CONFIG_COPY_PATH, envs.DEFAULT_CONFIG_PATH, str(e)) -# return base_config - -# corrected_config = _validate_config(user_config, fallback_config=base_config) - - -# return corrected_config - - -def _validate_config(config, fallback_config=None): - - folder_path = os.path.dirname(os.path.abspath(__file__)) - schema_path = os.path.join(folder_path, "config_schema.json") - - with open(schema_path, "r") as f: - schema = json.load(f) - - corrected_config = copy.deepcopy(config) - - # Checking if the config file has the required sections and options - for section in schema.keys(): - - if section not in config.keys(): - raise ConfigError("Cannot find header for section [%s]" % section) - - for option in schema[section].keys(): - - if option not in config[section].keys(): - raise ConfigError( - 'Cannot find option "%s" in section [%s]' % (option, section) - ) - - valid, msg = _validate_option( - schema[section][option], config[section][option] - ) - - if not valid: - error_msg = ( - 'Config parsing : error in option "%s" in section [%s] : %s' - % (option, section, msg) - ) - if fallback_config is not None: - print(error_msg) - print( - 'Falling back to default value "%s"', - fallback_config[section][option], - ) - corrected_config[section][option] = fallback_config[section][option] - - else: - raise ConfigError(error_msg) - - # Checking if the config file has no unknown section or option - for section in config.keys(): - - if section not in schema.keys(): - print("Config parsing : unknown section [%s]. Ignoring.", section) - continue - - for option in config[section].keys(): - if option not in schema[section].keys(): - print( - 'Config parsing : unknown option "%s" in section [%s]. Ignoring.', - option, - section, - ) - del corrected_config[section][option] - - return corrected_config - - -def _parsed_config_to_dict(config): - - config_dict = {} - - for section in config.keys(): - - if section == "DEFAULT": - continue - - config_dict[section] = {} - - for option in config[section].keys(): - config_dict[section][option] = config[section][option] - - return config_dict - - -def _validate_option(schema_option_info, config_option_value): - valid = False - msg = "error" - - parameter_type = schema_option_info[0] - - assert parameter_type in ["multi_words", "single_word", "integer"] - - # Multiple-words parameters - if parameter_type == "multi_words": - valid, msg = _validate_multi_words(schema_option_info, config_option_value) - - # Single-word parameters - elif parameter_type == "single_word": - valid, msg = _validate_single_word(schema_option_info, config_option_value) - - # Integer parameter - elif parameter_type == "integer": - valid, msg = _validate_integer(schema_option_info, config_option_value) - - return valid, msg - - -def _validate_multi_words(schema_option_info, config_option_value): - - parameter_type, allowed_values, can_be_blank = schema_option_info - assert parameter_type == "multi_words" - - values = config_option_value.replace(" ", "").split(",") - - if values == [""]: - if not can_be_blank: - msg = "at least one parameter required" - return False, msg - - else: - for val in values: - if val not in allowed_values: - msg = 'invalid value "%s"' % val - return False, msg - - return True, None - - -def _validate_single_word(schema_option_info, config_option_value): - - parameter_type, allowed_values, can_be_blank = schema_option_info - assert parameter_type == "single_word" - - val = config_option_value.replace(" ", "") - - if val == "": - if not can_be_blank: - msg = "non-blank value required" - return False, msg - - else: - if val not in allowed_values: - msg = 'invalid value "%s"' % val - return False, msg - - return True, None - - -def _validate_integer(schema_option_info, config_option_value): - - parameter_type, can_be_blank = schema_option_info - assert parameter_type == "integer" - - val = config_option_value.replace(" ", "") - - if val == "": - if not can_be_blank: - msg = "non-blank integer value required" - return False, msg - - else: - try: - v = int(val) - if v <= 0: - raise ValueError - except ValueError: - msg = "non-blank integer value required" - return False, msg - - return True, None diff --git a/fetch_cord/config_schema.json b/fetch_cord/config_schema.json deleted file mode 100755 index 2209dc3..0000000 --- a/fetch_cord/config_schema.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "cycle_0": - { - "top_line": ["single_word", ["kernel", "packages"], false], - "bottom_line": ["single_word", ["kernel", "packages"], false], - "de_wm_icon": ["single_word", ["on", "off"], true], - "time": ["single_word", ["15", "30", "45", "60", "75", "90", "105", "120", "240", "480"], false] - }, - - "cycle_1": - { - "top_line": ["single_word", ["cpu", "gpu", "mem", "disk"], false], - "bottom_line": ["single_word", ["cpu", "gpu", "mem", "disk"], false], - "gpu_icon": ["single_word", ["on", "off"], true], - "time": ["single_word", ["15", "30", "45", "60", "75", "90", "105", "120", "240", "480"], false] - }, - - "cycle_2": - { - "top_line": ["single_word", ["font", "shell", "theme"], false], - "bottom_line": ["single_word", ["font", "shell", "theme"], false], - "shell_icon": ["single_word", ["on", "off"], true], - "time": ["single_word", ["15", "30", "45", "60", "75", "90", "105", "120", "240", "480"], false] - }, - - "cycle_3": - { - "top_line": ["single_word", ["resolution", "battery", "host"], false], - "bottom_line": ["single_word", ["resolution", "battery", "host"], false], - "lapordesk_icon": ["single_word", ["on", "off"], true], - "time": ["single_word", ["15", "30", "45", "60", "75", "90", "105", "120", "240", "480"], false] - } -} diff --git a/fetch_cord/cycles.py b/fetch_cord/cycles.py deleted file mode 100755 index 56ba2e8..0000000 --- a/fetch_cord/cycles.py +++ /dev/null @@ -1,269 +0,0 @@ -#from __future__ import annotations - -import time -from typing import Dict - -from .computer.Computer import Computer -from .run_rpc import Run_rpc -from .args import parse_args - -args = parse_args() - - -class Cycles: - config: Dict[str, str] - - def __init__(self, config: Dict[str, str]): - self.config = config - - -def pause(run: Run_rpc, key: str, computer: Computer): - if args.debug: - print("pause_cycle") - if args.time: - time.sleep(int(args.time)) - else: - time.sleep(30) - - -def windows(run: Run_rpc, key: str, computer: Computer): - if args.debug: - print("w_cycle 0") - - run.try_update( - key, - state=computer.osinfo, - details=computer.memory, - large_image="big", - large_text=computer.osinfo, - small_image=computer.motherboardid, - small_text=computer.motherboard, - start=computer.uptime, - ) - - if args.time: - time.sleep(int(args.time)) - elif args.nohardware: - time.sleep(9999) - else: - time.sleep(30) - run.try_clear(key) - - -def runmac(run: Run_rpc, key: str, computer: Computer): - if args.debug: - print("runmac") - print("devicetype: %s" % computer.devicetype) - print("product %s" % computer.product) - print("bigicon: %s" % computer.bigicon) - print("ver: %s" % computer.version) - print("uptime: %s" % computer.uptime) - - run.try_update( - key, - state=computer.packages, # update state as packages - details=computer.kernel, # update details as kernel - large_image=computer.bigicon, # set icon - large_text=computer.osinfo, # set large icon text - small_image=computer.devicetype, # set small image icon - small_text=computer.product, # set small image text - start=computer.uptime, - ) - if args.time: - time.sleep(int(args.time)) - elif args.nohost and args.nohardware and args.noshell: - time.sleep(9999) - else: - time.sleep(30) - run.try_clear(key) - - -def cycle0(run: Run_rpc, key: str, computer: Computer): - top_line = run.config["cycle_0"]["top_line"] - if top_line == "kernel": - top_line = computer.kernel - else: - top_line = computer.packages - bottom_line = run.config["cycle_0"]["bottom_line"] - if bottom_line == "kernel": - bottom_line = computer.kernel - else: - bottom_line = computer.packages - de_wm_icon = run.config["cycle_0"]["de_wm_icon"] - if de_wm_icon == "on": - de_wm_icon = computer.desktopid - else: - de_wm_icon = "off" - if args.debug: - print("cycle 0") - - run.try_update( - key, - state=bottom_line, - details=top_line, - large_image="big", - large_text=computer.osinfo, - small_image=de_wm_icon, - small_text=computer.dewmid, - start=computer.uptime, - ) - if args.debug: - print("appid: %s" % computer.osinfoid) - config_time = run.config["cycle_0"]["time"] - if args.time: - time.sleep(int(args.time)) - elif args.nohost and args.nohardware and args.noshell: - time.sleep(9999) - elif config_time: - time.sleep(int(config_time)) - else: - time.sleep(30) - run.try_clear(key) - - -def cycle1(run: Run_rpc, key: str, computer: Computer): - top_line = run.config["cycle_1"]["top_line"] - if top_line == "gpu": - top_line = computer.gpu - elif top_line == "cpu": - top_line = computer.cpu - elif top_line == "mem": - top_line = computer.memory - elif top_line == "disk": - top_line = computer.disks - bottom_line = run.config["cycle_1"]["bottom_line"] - if bottom_line == "gpu": - bottom_line = computer.gpu - elif bottom_line == "cpu": - bottom_line = computer.cpu - elif bottom_line == "mem": - bottom_line = computer.memory - elif bottom_line == "disk": - bottom_line = computer.disks - gpu_icon = run.config["cycle_1"]["gpu_icon"] - if gpu_icon == "on": - gpu_icon = computer.gpuid - else: - gpu_icon = "off" - if args.debug: - print("cycle 1") - run.try_update( - key, - state=bottom_line, - details=top_line, - large_image="big", - large_text=computer.cpu, - small_image=gpu_icon, - small_text=computer.gpu, - start=computer.uptime, - ) - if args.debug: - print("appid: %s" % computer.cpuid) - config_time = run.config["cycle_1"]["time"] - if args.time: - time.sleep(int(args.time)) - elif args.nodistro and args.noshell and args.nohost: - time.sleep(9999) - elif config_time: - time.sleep(int(config_time)) - else: - time.sleep(30) - run.try_clear(key) - - -def cycle2(run: Run_rpc, key: str, computer: Computer): - top_line = run.config["cycle_2"]["top_line"] - if top_line == "font": - top_line = computer.terminal - elif top_line == "shell": - top_line = computer.shellid - elif top_line == "theme": - top_line = computer.theme - bottom_line = run.config["cycle_2"]["bottom_line"] - if bottom_line == "font": - bottom_line = computer.terminal - elif bottom_line == "shell": - bottom_line = computer.shell - elif bottom_line == "theme": - bottom_line = computer.theme - shell_icon = run.config["cycle_2"]["shell_icon"] - if shell_icon == "on": - shell_icon = computer.shellid - else: - shell_icon = "off" - if args.debug: - print("cycle 2") - - run.try_update( - key, - state=bottom_line, - details=top_line, - large_image="big", - large_text=computer.terminal, - small_image=shell_icon, - small_text=computer.shell, - start=computer.uptime, - ) - if args.debug: - print("appid: %s" % computer.osinfoid) - - config_time = run.config["cycle_2"]["time"] - - if args.time: - time.sleep(int(args.time)) - elif args.nodistro and args.nohardware and args.nohost: - time.sleep(9999) - elif config_time: - time.sleep(int(config_time)) - else: - time.sleep(30) - run.try_clear(key) - - -def cycle3(run: Run_rpc, key: str, computer: Computer): - # if not then forget it - if computer.host != "Host: N/A": - top_line = run.config["cycle_3"]["top_line"] - if top_line == "battery": - top_line = computer.battery - elif top_line == "host": - top_line = computer.host - elif top_line == "resolution": - top_line = computer.resolution - bottom_line = run.config["cycle_3"]["bottom_line"] - if bottom_line == "resolution": - bottom_line = computer.resolution - elif bottom_line == "host": - bottom_line = computer.host - elif bottom_line == "battery": - bottom_line = computer.battery - lapordesk_icon = run.config["cycle_3"]["lapordesk_icon"] - if lapordesk_icon == "on": - lapordesk_icon = computer.lapordesk - else: - lapordesk_icon = "off" - if args.debug: - print("cycle 3") - run.try_update( - key, - state=computer.resolution, - details=computer.battery, - large_image="big", - large_text=computer.host, - small_image=lapordesk_icon, - small_text=computer.lapordesk, - start=computer.uptime, - ) - if args.debug: - print("appid: %s" % computer.hostappid) - config_time = run.config["cycle_3"]["time"] - if args.time: - time.sleep(int(args.time)) - elif args.nodistro and args.nohardware and args.noshell: - time.sleep(9999) - elif config_time: - time.sleep(int(config_time)) - else: - time.sleep(30) - # back from whence you came - run.try_clear(key) diff --git a/fetch_cord/debugger.py b/fetch_cord/debugger.py deleted file mode 100755 index 1403cc6..0000000 --- a/fetch_cord/debugger.py +++ /dev/null @@ -1,83 +0,0 @@ -#from __future__ import annotations - -from typing import List - -from .computer.Computer import Computer -from .computer.cpu.Cpu_interface import Cpu_interface - - -def run_debug(computer: Computer): - print("----out.py----\n") - print("----DE/WM----") - if computer.os != "windows": - print("deid: %s" % computer.deid) - print("wmid: %s" % computer.wmid) - try: - print("wmline item 0: %s" % computer.wm) - except IndexError: - pass - print("\n----TERMINAL----\n") - print("fontline: %s" % computer.font) - print("termid: %s" % computer.terminalid) - print("termline item 0: %s" % computer.terminal) - print("themeline: %s" % computer.theme) - if computer.host != "Host: N/A": - print("\n----HOST INFO----\n") - print("hostline: %s" % computer.host) - if computer.battery != computer.host: - print("batteryline: %s" % computer.battery) - print("resline: %s" % computer.resolution) - print("\n----GPU INFO----\n") - print("gpuinfo: %s" % computer.gpu) - print("gpuvendor: %s" % computer.gpuid) - print("\n----CPU INFO----\n") - cpu: List[Cpu_interface] = computer.get_component("CPU:") - if cpu: - print("cpuvendor: %s" % cpu[0].vendor) - print("cpumodel: %s" % cpu[0].model) - print("cpuinfo: %s" % cpu[0].info) - print("cpuline item 0: %s" % computer.cpu) - print("memline: %s" % computer.memory) - print("\n----OS INFO----\n") - print("sysosline: %s" % computer.osinfo) - print("sysosid: %s" % computer.osinfoid) - print("diskline: %s" % computer.disks) - if computer.os != "windows": - print("packagesline item 0: %s" % computer.packages) - - -def test_debug(computer: Computer): - print("\n----testing.py----") - if computer.os != "windows": - print("----DE/WM----\n") - print("deid: %s" % computer.deid) - print("wmid: %s" % computer.wmid) - print("\n----TERMINAL/SHELL----\n") - print("termid: %s" % computer.terminalid) - print("shellid: %s" % computer.shellid) - print("\n----HOST INFO----\n") - print("hostid: %s" % computer.hostid) - else: - print("moboid: %s" % computer.motherboardid) - print("moboline: %s" % computer.motherboard) - print("\n----GPU INFO----\n") - print("gpuvendor: %s" % computer.gpuid) - print("\n----CPU INFO----\n") - cpu = computer.get_component("CPU:") - if cpu: - print("cpumodel: %s\n" % cpu[0].model) - - -def run_rpc_debug(computer: Computer): - print("----run_rpc----\n") - print("uptime in epoch: %s" % computer.uptime) - print("cpuid: %s" % computer.osinfoid) - print("cpuappid: %s" % computer.cpuid) - if computer.os != "windows": - print("termappid: %s" % computer.terminalid) - if computer.host != "Host: N/A": - print("hostappid: %s" % computer.hostappid) - print(computer.packages) - - run_debug(computer) - test_debug(computer) \ No newline at end of file diff --git a/fetch_cord/computer/flatpak.py b/fetch_cord/flatpak.py old mode 100755 new mode 100644 similarity index 88% rename from fetch_cord/computer/flatpak.py rename to fetch_cord/flatpak.py index 0776f4e..e801a98 --- a/fetch_cord/computer/flatpak.py +++ b/fetch_cord/flatpak.py @@ -1,6 +1,6 @@ -#from __future__ import annotations +# from __future__ import annotations -from fetch_cord.run_command import BashError, exec_bash +from fetch_cord.Tools import BashError, exec_bash import os diff --git a/fetch_cord/computer/resources.py b/fetch_cord/get_resources.py old mode 100755 new mode 100644 similarity index 77% rename from fetch_cord/computer/resources.py rename to fetch_cord/get_resources.py index 94ff984..2272ebe --- a/fetch_cord/computer/resources.py +++ b/fetch_cord/get_resources.py @@ -1,4 +1,4 @@ -#from __future__ import annotations +# from __future__ import annotations try: @@ -8,7 +8,7 @@ import importlib_resources as pkg_resources import json -from .. import resources as fc_resources +from fetch_cord import resources as fc_resources def get_infos(): @@ -18,8 +18,6 @@ def get_infos(): return infos -def get_default_config(): +def get_default_config() -> str: with pkg_resources.path(fc_resources, "default.conf") as path: return path - - return None diff --git a/fetch_cord/native/Windows/__init__.py b/fetch_cord/native/Windows/__init__.py new file mode 100644 index 0000000..0149df4 --- /dev/null +++ b/fetch_cord/native/Windows/__init__.py @@ -0,0 +1,18 @@ +import os + +if os.name == "nt": + from typing import Optional + from . import packages + + def fetch(component_class: str) -> Optional[str | None]: + fetch_map = {"packages": packages} + + if component_class not in fetch_map: + return None + + return fetch_map[component_class].fetch() + +else: + + def fetch(component_class: str) -> None: + return "Not implemented for this platform." diff --git a/fetch_cord/native/Windows/packages.py b/fetch_cord/native/Windows/packages.py new file mode 100644 index 0000000..ff784ba --- /dev/null +++ b/fetch_cord/native/Windows/packages.py @@ -0,0 +1,25 @@ +import winreg + + +def get_installed_software(): + software_list = [] + software_path = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall" + with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, software_path) as software: + try: + for i in range(0, winreg.QueryInfoKey(software)[0]): + software_name = winreg.EnumKey(software, i) + with winreg.OpenKey(software, software_name) as subkey: + try: + software_list.append( + winreg.QueryValueEx(subkey, "DisplayName")[0] + ) + except EnvironmentError: + pass + except WindowsError: + pass + + return software_list + + +def fetch() -> str: + return f"{len(get_installed_software())} packages" diff --git a/fetch_cord/computer/__init__.py b/fetch_cord/native/__init__.py old mode 100755 new mode 100644 similarity index 100% rename from fetch_cord/computer/__init__.py rename to fetch_cord/native/__init__.py diff --git a/fetch_cord/native/native.py b/fetch_cord/native/native.py new file mode 100644 index 0000000..b851cf8 --- /dev/null +++ b/fetch_cord/native/native.py @@ -0,0 +1,15 @@ +import platform +from typing import Optional + +from fetch_cord.native import Windows + +fetch_map = {"Windows": Windows} + + +def fetch(component_class: str) -> Optional[str | None]: + sys_platform = platform.system() + + if sys_platform not in fetch_map: + return None + + return fetch_map[sys_platform].fetch(component_class) diff --git a/fetch_cord/resources/cpus.json b/fetch_cord/resources/cpus.json new file mode 100644 index 0000000..bf84a9a --- /dev/null +++ b/fetch_cord/resources/cpus.json @@ -0,0 +1,83 @@ +{ + "741153175779803146": [ + "(?i)Ryzen 3" + ], + "741152732756312125": [ + "(?i)Ryzen 5" + ], + "740752899054895105": [ + "(?i)Ryzen 7" + ], + "741152930899427364": [ + "(?i)Ryzen 9" + ], + "742075019257184338": [ + "(?i)^.*(Ryzen.*Threadripper|Threadripper.*Ryzen).*$" + ], + "820717165329645618": [ + "a4 apu", + "(?i)^.*(A4.*APU|APU.*A4).*$" + ], + "820711517715693608": [ + "a6 apu", + "(?i)^.*(A6.*APU|APU.*A6).*$" + ], + "820715505437638708": [ + "(?i)^.*(A8.*APU|APU.*A8).*$" + ], + "820738634473930752": [ + "(?i)^.*(A9.*APU|APU.*A9).*$" + ], + "820726638635122740": [ + "(?i)^.*(A10.*APU|APU.*A10).*$" + ], + "820737378494054451": [ + "(?i)^.*(A12.*APU|APU.*A12).*$" + ], + "820739431711113226": [ + "(?i)^.*(FX.*APU|APU.*FX).*$" + ], + "870365152401293452": [ + "(?i)^.*(athlon.*silver|silver.*athlon).*$", + "(?i)^.*(athlon.*gold|gold.*athlon).*$" + ], + "741044208512532570": [ + "(?i)Intel i3", + "(?i)intel.*core.*i3.*" + ], + "741099939198926920": [ + "(?i)Intel i5", + "(?i)intel.*core.*i5.*" + ], + "741100300219187335": [ + "(?i)Intel i7", + "(?i)intel.*core.*i7.*" + ], + "741100622040006719": [ + "(?i)Intel i9", + "(?i)intel.*core.*i9.*" + ], + "741203845706940467": [ + "(?i)^.*(intel.*pentium|pentium.*intel).*$", + "(?i)pentium", + "(?i)intel.*core.*pentium.*" + ], + "742904581360713849": [ + "(?i)Intel celeron", + "(?i)celeron" + ], + "746527640382603375": [ + "(?i)Intel core 2 duo", + "intel2 duo" + ], + "785615606438166544": [ + "(?i)Intel core 2 quad", + "intel2 quad" + ], + "749011141090607144": [ + "(?i)Intel xeon" + ], + "742887089179197462": [ + "unknown" + ] +} \ No newline at end of file diff --git a/fetch_cord/resources/default.conf b/fetch_cord/resources/default.conf index 0144504..d91d5b0 100755 --- a/fetch_cord/resources/default.conf +++ b/fetch_cord/resources/default.conf @@ -23,12 +23,12 @@ print_info() { info "Memory" memory info "Battery" battery info "Disk" disk + info "Font" font # info "GPU Driver" gpu_driver # Linux/macOS only # info "CPU Usage" cpu_usage # info "Disk" disk # info "Battery" battery - # info "Font" font # info "Song" song # [[ "$player" ]] && prin "Music Player" "$player" # info "Local IP" local_ip @@ -848,4 +848,4 @@ background_color= # Useful for piping into another command. # Default: 'off' # Values: 'on', 'off' -stdout="off" +stdout="on" \ No newline at end of file diff --git a/fetch_cord/resources/desktop.json b/fetch_cord/resources/desktop.json new file mode 100644 index 0000000..a72fe14 --- /dev/null +++ b/fetch_cord/resources/desktop.json @@ -0,0 +1,44 @@ +{ + "kde": [ + "(?i)kde" + ], + "plasma": [ + "(?i)plasma" + ], + "xfce": [ + "(?i)xfce" + ], + "mate": [ + "(?i)mate" + ], + "budgie": [ + "(?i)budgie" + ], + "gnome": [ + "(?i)gnome" + ], + "cinnamon": [ + "(?i)cinnamon" + ], + "aero": [ + "(?i)aero" + ], + "pantheon": [ + "(?i)pantheon" + ], + "explorer": [ + "(?i)explorer" + ], + "lxde": [ + "(?i)lxde" + ], + "lxqt": [ + "(?i)lxqt" + ], + "unity": [ + "(?i)unity" + ], + "deepin": [ + "(?i)deepin" + ] +} \ No newline at end of file diff --git a/fetch_cord/resources/fetch_cord.conf b/fetch_cord/resources/fetch_cord.conf deleted file mode 100755 index 5917e08..0000000 --- a/fetch_cord/resources/fetch_cord.conf +++ /dev/null @@ -1,47 +0,0 @@ -[cycle_0] - -# Order to set info in discord presence, valid values are: kernel, packages -top_line=kernel -bottom_line=packages -# show small_icon in Discord -de_wm_icon=on - -# Duration to show this cycle -# valid values are, 15, 30, 45, 60, 75, 90, 105, 120, 240, and 480 -time=30 - -[cycle_1] - -# Order to set info in discord presence, valid values are: mem, gpu, cpu, and disk -top_line=mem -bottom_line=gpu -# show small_icon in Discord -gpu_icon=on - -# Duration to show this cycle -# valid values are, 15, 30, 45, 60, 75, 90, 105, 120, 240, and 480 -time=30 - -[cycle_2] - -# Order to set info in discord presence, valid values are: font, shell, and theme -top_line=font -bottom_line=shell -# show small_icon in Discord -shell_icon=on - -# Duration to show this cycle -# valid values are, 15, 30, 45, 60, 75, 90, 105, 120, 240, and 480 -time=30 - -[cycle_3] - -# Order to set info in discord presence, valid values are: battery, resolution, and host -top_line=battery -bottom_line=resolution -# show small_icon in Discord -lapordesk_icon=on - -# Duration to show this cycle -# valid values are, 15, 30, 45, 60, 75, 90, 105, 120, 240, and 480 -time=30 \ No newline at end of file diff --git a/fetch_cord/resources/fetchcord_cmds.yml b/fetch_cord/resources/fetchcord_cmds.yml new file mode 100644 index 0000000..6c0ae34 --- /dev/null +++ b/fetch_cord/resources/fetchcord_cmds.yml @@ -0,0 +1,143 @@ +--- +commands: + cpu: + Windows: | + Get-WmiObject -Class Win32_Processor -ComputerName. | Select-Object -Property Name | ForEach-Object {$_.Name} + Linux: &cpu_sh | + lscpu | grep "Model name:" | cut -d: -f2 | xargs + Darwin: | + sysctl -n machdep.cpu.brand_string + gpu: + Windows: | + Get-WmiObject Win32_VideoController | Select-Object Name | ForEach-Object {$_.Name} + Linux: | + lspci -mm | grep -e 3D -e VGA | cut -d " " -f1 --complement | sed 's/[^"]*"\([^"]*\)"/"\1" /g' | python3 -c "import sys; print('\"' + '\" \"'.join([part for part in sys.stdin.read().strip().split('\"') if part.strip()][-2:]) + '\"')" | sed -e 's/" "/\t/g' -e 's/\"//g' | xargs + Darwin: | + system_profiler SPDisplaysDataType | grep 'Chipset Model' | xargs| cut -d " " -f3- | sed -e 's/" "/\t/g' -e 's/\"//g' | cut -f1- + mem: + Windows: | + # Get total physical memory (in bytes) + $TotalMemory = (Get-CimInstance -ClassName Win32_ComputerSystem).TotalPhysicalMemory + + # Get available physical memory (in bytes) + $AvailableMemory = (Get-CimInstance -ClassName Win32_PerfFormattedData_PerfOS_Memory).AvailableBytes + + # Convert values to GB + $TotalMemory = [int64]$TotalMemory/1024/1024/1024 + $AvailableMemory = [int64]$AvailableMemory/1024/1024/1024 + + # Calculate used memory + $UsedMemory = $TotalMemory - $AvailableMemory + + # Output used and total memory in GB + Write-Output ("{0:N2} GB / {1:N2} GB" -f $UsedMemory, $TotalMemory) + Linux: &mem_sh | + # Get total physical memory (in bytes) + TotalMemory=$(cat /proc/meminfo | grep MemTotal | awk '{print $2}') + + # Get available physical memory (in bytes) + AvailableMemory=$(cat /proc/meminfo | grep MemFree | awk '{print $2}') + + # Convert values to GB + TotalMemory=$(awk "BEGIN {printf \"%.2f\", $TotalMemory / 1024 / 1024}") + AvailableMemory=$(awk "BEGIN {print $AvailableMemory / 1024 / 1024}") + + # Calculate used memory + UsedMemory=$(awk "BEGIN {printf \"%.2f\", $TotalMemory - $AvailableMemory}") + + # Output used and total memory in GB + echo "$UsedMemory GB / $TotalMemory GB" + Darwin: | + # Get total physical memory (in bytes) + TotalMemory=$(sysctl -n hw.memsize) + + # Get free memory in pages + FreePages=$(vm_stat | grep 'Pages free:' | awk '{print $3}' | sed 's/\.//') + + # Get the page size in bytes (usually 4096) + PageSize=$(vm_stat | grep 'page size of' | awk '{print $8}') + + # Calculate free memory in bytes + AvailableMemory=$(($FreePages * $PageSize)) + + # Convert values to GB + TotalMemory=$(awk "BEGIN {printf \"%.2f\", $TotalMemory / 1024 / 1024 / 1024}") + AvailableMemory=$(awk "BEGIN {print $AvailableMemory / 1024 / 1024 / 1024}") + + # Calculate used memory + UsedMemory=$(awk "BEGIN {printf \"%.2f\", $TotalMemory - $AvailableMemory}") + + # Output used and total memory in GB + echo "$UsedMemory GB / $TotalMemory GB" + kernel: + Windows: | + Get-CimInstance -ClassName Win32_OperatingSystem | Select-Object Version | ForEach-Object {$_.Version} + Linux: &kernel_sh | + fastfetch -l none | grep "Kernel" | awk -F: '{print $2}' | sed 's/^\s*//' + Darwin: *kernel_sh + packages: + Linux: &packages_sh | + fastfetch -l none | grep "Packages" | awk -F: '{print $2}' | sed 's/^\s*//' + Darwin: *packages_sh + os: + Windows: | + Get-CimInstance Win32_OperatingSystem | Select-Object Caption | ForEach-Object {$_.Caption} + Linux: &os_sh | + fastfetch -l none | grep "OS" | awk -F: '{print $2}' | sed 's/^\s*//' + Darwin: *os_sh + host: + Windows: | + Get-WmiObject Win32_BaseBoard | Select-Object Product | ForEach-Object {$_.Product} + Linux: &host_sh | + fastfetch -l none | grep "Host" | awk -F: '{print $2}' | sed 's/^\s*//' + Darwin: *host_sh + motherboard: + Windows: | + Get-CimInstance -ClassName Win32_BaseBoard | Select-Object Manufacturer | ForEach-Object {$_.Manufacturer} + Linux: &motherboard_sh | + cat /sys/devices/virtual/dmi/id/board_{vendor,name} | xargs + Darwin: | + model_name=$(system_profiler SPHardwareDataType | awk -F: '/Model Name/ {print $2}') + model_identifier=$(system_profiler SPHardwareDataType | awk -F: '/Model Identifier/ {print $2}') + + echo "${model_name}${model_identifier}" + resolution: + Windows: | + Get-CimInstance -ClassName Win32_DesktopMonitor | Select-Object ScreenWidth, ScreenHeight | ForEach-Object { $_.ScreenWidth.ToString() + 'x' + $_.ScreenHeight.ToString() } + Linux: &resolution_sh | + xdpyinfo | awk '/dimensions/ {print $2}' + Darwin: *resolution_sh + system_type: + Windows: | + Get-CimInstance Win32_Battery | Select-Object BatteryStatus | ForEach-Object {$_.BatteryStatus} + Linux: &battery_sh | + if ls /sys/class/power_supply/ | grep -qi battery; then echo "laptop"; else echo "desktop"; fi + Darwin: | + if pmset -g batt | grep -qi battery; then echo "laptop"; else echo "desktop"; fi + shell: + Windows: | + Write-Host "PowerShell $(($PSVersionTable).PSVersion)" + Linux: &shell_sh | + fastfetch -l none | grep "Shell" | awk -F: '{print $2}' | sed 's/^\s*//' + Darwin: *shell_sh + font: + Windows: | + $Font = (Get-ItemProperty -Path "HKCU:\Console").FaceName + + if ($Font -eq "__DefaultTTFont__") { + $RegistryPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Console\TrueTypeFont" + $DefaultFont = (Get-ItemProperty -Path $RegistryPath).00 + Write-Host "$DefaultFont" + } + else { + Write-Host "$Font" + } + Linux: &font_sh | + fastfetch -l none | grep "Font" | awk -F: '{print $2}' | sed 's/^\s*//' + Darwin: *font_sh + terminal: + Windows: | + $host.Name + Linux: &terminal_sh | + fastfetch -l none | grep "Terminal" | awk -F: '{print $2}' | sed 's/^\s*//' + Darwin: *terminal_sh diff --git a/fetch_cord/resources/fetchcord_conf.yml b/fetch_cord/resources/fetchcord_conf.yml new file mode 100644 index 0000000..28bc54b --- /dev/null +++ b/fetch_cord/resources/fetchcord_conf.yml @@ -0,0 +1,27 @@ +--- +cycle_time: &cycle_time 30 +cycles: + - name: os + app_id: os + top_line: kernel + bottom_line: packages + small_icon: system_type + time: *cycle_time + - name: hardware + app_id: cpu + top_line: mem + bottom_line: gpu + small_icon: gpu + time: *cycle_time + - name: shell + app_id: terminal + top_line: font + bottom_line: shell + small_icon: shell + time: *cycle_time + - name: host + app_id: motherboard + top_line: motherboard + bottom_line: resolution + small_icon: system_type + time: *cycle_time diff --git a/fetch_cord/resources/fetchcord_ids.json b/fetch_cord/resources/fetchcord_ids.json deleted file mode 100755 index eb31b87..0000000 --- a/fetch_cord/resources/fetchcord_ids.json +++ /dev/null @@ -1,178 +0,0 @@ -{ - "map": { - "GPU:": "gpu", - "CPU:": "cpu", - "Terminal:": "terminal", - "Motherboard:": "motherboard", - "Host:": "motherboard", - "Shell:": "shell", - "OS:": "distro", - "DE:": "desktop", - "WM:": "windowmanager", - "Version:": "version" - }, - "gpu": { - "amd": "amd", - "radeon": "amd", - "amdnvidia": "nvidiaamd", - "amdintel": "amdintel", - "nvidia": "nvidia", - "nvidiaamd": "nvidiaamd", - "nvidiaintel": "nvidiaintel", - "intel": "intel", - "intelamd": "amdintel", - "intelnvidia": "nvidiaintel", - "vmware": "vmware", - "virtio": "virtio", - "cirrus": "cirrus", - "unknown": "off" - }, - "cpu": { - "amd": { - "ryzen 3": "741153175779803146", - "ryzen 5": "741152732756312125", - "ryzen 7": "740752899054895105", - "ryzen 9": "741152930899427364", - "ryzen threadripper": "742075019257184338", - "a4 apu": "820717165329645618", - "a6 apu": "820711517715693608", - "a8 apu": "820715505437638708", - "a9 apu": "820738634473930752", - "a10 apu": "820726638635122740", - "a12 apu": "820737378494054451", - "fx apu": "820739431711113226" - }, - "intel": { - "intel i3": "741044208512532570", - "intel i5": "741099939198926920", - "intel i7": "741100300219187335", - "intel i9": "741100622040006719", - "intel pentium": "741203845706940467", - "intel celeron": "742904581360713849", - "pentium": "741203845706940467", - "intel core 2 duo": "746527640382603375", - "intel core 2 quad": "785615606438166544", - "intel xeon": "749011141090607144" - }, - "unknown": "742887089179197462" - }, - "terminal": { - "st": "741280043220861030", - "kitty": "741285676250824725", - "alacritty": "741291339945345045", - "xterm": "741287143187546125", - "konsole": "741286819676553258", - "dolphin": "741286819676553258", - "gnome-terminal": "741328861115056160", - "cool-retro-term": "741731097498353794", - "urxvt": "743246048968835092", - "xfce4-terminal": "744332423072055296", - "apple_terminal": "744950796298354689", - "lxterminal": "745701997503840380", - "yakuake": "741286819676553258", - "mate-terminal": "746531413360377856", - "unknown": "745691250186911796" - }, - "motherboard": { - "asrock": "811349714946490408", - "aorus": "749061181607772200", - "inspiron": "743970870631858288", - "latitude": "743970870631858288", - "g3": "743970870631858288", - "hp": "743971270395297852", - "tuf": "744330890343219262", - "asus": "743936082780880928", - "asustek": "743936082780880928", - "acer": "744326890512318544", - "KBL (Metapod_KL)": "744326890512318544", - "thinkpad": "744326223412461630", - "ideapad": "744326223412461630", - "lenovo": "744326223412461630", - "gigabyte": "746447043190456561", - "Z370XP SLI": "746447043190456561", - "macbookair,": "748290608787095694", - "macbookpro,": "750016315854553138", - "aspire": "744326890512318544", - "hvm": "749014556604497972", - "dell": "785620748021792788", - "msi": "787106184783200266", - "optiplex 780": "785620748021792788", - "optiplex": "785620748021792788", - "H310M A 2.0": "746447043190456561", - "K53TA 1.0": "743936082780880928", - "MS-7C02 1.0": "787106184783200266", - "unknown": "742887089179197462" - }, - "shell": { - "fish": "fish", - "zsh": "zsh", - "bash": "bash", - "tcsh": "tcsh", - "ruby": "ruby", - "unknown": "unknown" - }, - "distro": { - "ubuntu": "740434138036699178", - "opensuseleap": "740156532137787433", - "arch": "740476198437650473", - "arco": "745435867971321866", - "artix": "741918141248045107", - "fedora": "740485660703719464", - "void": "740484961353597039", - "gentoo/linux": "740484380652208140", - "funtoo": "740484380652208140", - "centos": "740483295388631071", - "debian": "740490017218232392", - "opensusetumbleweed": "742180413132505088", - "manjaro": "740614258177605642", - "linuxmint": "740633577481568317", - "lmde": "741726946588622988", - "pop!_os": "740660055925587978", - "endeavouros": "740809641545564170", - "windows10": "741949889465942099", - "windows7": "741952383512346696", - "windows8": "741952179488948324", - "windows8.1": "741952065294827520", - "nixos": "744644133494325329", - "instantos": "744784599653285938", - "freebsd": "745054697047457822", - "solus": "745689115944681683", - "zorin": "745689865798156379", - "amazon": "749014983920320583", - "bedrock": "749015250904416287", - "garuda": "820649067695833118", - "unknown": "742993278143692821" - }, - "desktop": { - "kde": "kde", - "plasma": "plasma", - "xfce": "xfce", - "budgie": "budgie", - "gnome": "gnome", - "deepin": "deepin", - "cinnamon": "cinnamon", - "mate": "mate", - "aero": "aero", - "pantheon": "pantheon", - "explorer": "explorer", - "unknown": "unknown" - }, - "windowmanager": { - "dwm": "dwm", - "i3": "i3", - "awesome": "awesome", - "enlightenment": "enlightenment", - "bspwm": "bspwm", - "xmonad": "xmonad", - "sway": "sway", - "openbox": "openbox", - "herbstluftwm": "herbstluftwm", - "unknown": "unknown" - }, - "version": { - "10.13": "hsierria", - "10.14": "mojave", - "10.15": "catalina", - "unknown": "unknown" - } -} \ No newline at end of file diff --git a/fetch_cord/resources/gpus.json b/fetch_cord/resources/gpus.json new file mode 100644 index 0000000..8e81f93 --- /dev/null +++ b/fetch_cord/resources/gpus.json @@ -0,0 +1,37 @@ +{ + "amd": [ + "(?i)amd", + "(?i)radeon" + ], + "nvidia": [ + "(?i)nvidia", + "(?i)geforce" + ], + "intel": [ + "(?i)intel" + ], + "vmware": [ + "(?i)vmware" + ], + "virtio": [ + "(?i)virtio" + ], + "cirrus": [ + "(?i)cirrus" + ], + "nvidiaamd": [ + "nvidiaamd", + "amdnvidia" + ], + "amdintel": [ + "amdintel", + "intelamd" + ], + "nvidiaintel": [ + "nvidiaintel", + "intelnvidia" + ], + "off": [ + "unknown" + ] +} \ No newline at end of file diff --git a/fetch_cord/resources/motherboards.json b/fetch_cord/resources/motherboards.json new file mode 100644 index 0000000..29918cc --- /dev/null +++ b/fetch_cord/resources/motherboards.json @@ -0,0 +1,76 @@ +{ + "744326223412461630": [ + "(?i)lenovo", + "(?i)thinkpad", + "(?i)thinkbook", + "(?i)ideapad", + "(?i)legion", + "(?i)thinkcentre" + ], + "746447043190456561": [ + "(?i)gigabyte", + "(?i)Z370XP SLI", + "(?i)Z390 GAMING X", + "(?i)H310M A 2.0" + ], + "749061181607772200": [ + "(?i)aorus" + ], + "743970870631858288": [ + "(?i)inspiron", + "(?i)latitude", + "(?i)g3" + ], + "743971270395297852": [ + "(?i)hp", + "(?i)hewlett-packard", + "(?i)J7D10ET" + ], + "744330890343219262": [ + "(?i)tuf" + ], + "743936082780880928": [ + "(?i)asus", + "(?i)asustek", + "(?i)rog", + "(?i)republic of gamers", + "(?i)K53TA 1.0" + ], + "744326890512318544": [ + "(?i)acer", + "(?i)KBL (Metapod_KL)", + "(?i)aspire", + "(?i)DL (Tulip_DA)" + ], + "748290608787095694": [ + "(?i)macbook air" + ], + "750016315854553138": [ + "(?i)macbook pro" + ], + "749014556604497972": [ + "(?i)hvm" + ], + "785620748021792788": [ + "(?i)dell", + "(?i)alienware", + "(?i)inspiron", + "(?i)latitude", + "(?i)precision", + "(?i)vostro", + "(?i)xps", + "(?i)optiplex", + "(?i)optiplex 780" + ], + "787106184783200266": [ + "(?i)msi", + "(?i)MS-7C02 1.0", + "(?i)PE70 6QD REV:1.0" + ], + "811349714946490408": [ + "(?i)asrock" + ], + "742887089179197462": [ + "unknown" + ] +} \ No newline at end of file diff --git a/fetch_cord/resources/os.json b/fetch_cord/resources/os.json new file mode 100644 index 0000000..c1b41c4 --- /dev/null +++ b/fetch_cord/resources/os.json @@ -0,0 +1,111 @@ +{ + "1057793641525039185": [ + "(?i)Windows 11" + ], + "741949889465942099": [ + "(?i)Windows 10" + ], + "741952065294827520": [ + "(?i)Windows 8.1" + ], + "741952179488948324": [ + "(?i)Windows 8" + ], + "1057796703153037402": [ + "(?i)Windows 7" + ], + "877994542912114718": [ + "(?i)elementary" + ], + "740434138036699178": [ + "(?i)ubuntu" + ], + "740156532137787433": [ + "(?i)opensuseleap" + ], + "740476198437650473": [ + "(?i)arch" + ], + "745435867971321866": [ + "(?i)arco" + ], + "741918141248045107": [ + "(?i)artix" + ], + "740485660703719464": [ + "(?i)fedora" + ], + "740484961353597039": [ + "(?i)void" + ], + "740484380652208140": [ + "(?i)gentoo", + "(?i)funtoo" + ], + "740483295388631071": [ + "(?i)centos" + ], + "740490017218232392": [ + "(?i)debian" + ], + "742180413132505088": [ + "(?i)opensusetumbleweed" + ], + "740614258177605642": [ + "(?i)manjaro" + ], + "740633577481568317": [ + "(?i)linuxmint" + ], + "741726946588622988": [ + "(?i)lmde" + ], + "740660055925587978": [ + "(?i)pop!_os" + ], + "740809641545564170": [ + "(?i)endeavouros" + ], + "744644133494325329": [ + "(?i)nixos" + ], + "744784599653285938": [ + "(?i)instantos" + ], + "745054697047457822": [ + "(?i)freebsd" + ], + "745689115944681683": [ + "(?i)solus" + ], + "745689865798156379": [ + "(?i)zorin" + ], + "749014983920320583": [ + "(?i)amazon" + ], + "749015250904416287": [ + "(?i)bedrock" + ], + "820649067695833118": [ + "(?i)garuda" + ], + "852597254509297684": [ + "(?i)parrotos" + ], + "852619769551257650": [ + "(?i)rebornos" + ], + "852639226445299752": [ + "(?i)mageia" + ], + "1146166660521283674": [ + "(?i)mikicrep" + ], + "740822755376758944": [ + "(?i)macos" + ], + "742993278143692821": [ + "unknown" + ] +} \ No newline at end of file diff --git a/fetch_cord/resources/shell.json b/fetch_cord/resources/shell.json new file mode 100644 index 0000000..651d780 --- /dev/null +++ b/fetch_cord/resources/shell.json @@ -0,0 +1,20 @@ +{ + "fish": [ + "(?i)fish" + ], + "zsh": [ + "(?i)zsh" + ], + "bash": [ + "(?i)bash" + ], + "tcsh": [ + "(?i)tcsh" + ], + "ruby": [ + "(?i)ruby" + ], + "742887089179197462": [ + "unknown" + ] +} \ No newline at end of file diff --git a/fetch_cord/resources/system_types.json b/fetch_cord/resources/system_types.json new file mode 100644 index 0000000..fccb70c --- /dev/null +++ b/fetch_cord/resources/system_types.json @@ -0,0 +1,9 @@ +{ + "laptop": [ + "(?i)laptop" + ], + "desktop": [ + "(?i)desktop" + ], + "off": "unknown" +} \ No newline at end of file diff --git a/fetch_cord/resources/systemd_service.py b/fetch_cord/resources/systemd_service.py index 1479307..18e124f 100644 --- a/fetch_cord/resources/systemd_service.py +++ b/fetch_cord/resources/systemd_service.py @@ -1,8 +1,7 @@ #!/usr/bin/python3 -from os import system -from ..run_command import BashError, exec_bash -from ..args import parse_args +from fetch_cord.Tools import BashError, exec_bash +from fetch_cord.args import parse_args import sys args = parse_args() @@ -19,7 +18,7 @@ def systemd_cmd(cmd: str): def install(): try: exec_bash("mkdir -p ~/.local/share/systemd/user") - except: + except Exception: print("Error : Cannot create directory...") sys.exit(1) @@ -27,7 +26,7 @@ def install(): exec_bash( f"wget -O ~/.local/share/systemd/user/fetchcord.service https://raw.githubusercontent.com/MrPotatoBobx/FetchCord/{'testing' if args.testing else 'master'}/systemd/fetchcord.service", ) - except: + except Exception: print("Error: Failed to download the service file.") sys.exit(1) @@ -43,7 +42,7 @@ def uninstall(): try: exec_bash("rm -f ~/.local/share/systemd/user/fetchcord.service") - except: + except Exception: print("Error : Cannot remove service file...") sys.exit(1) @@ -72,4 +71,4 @@ def stop(): def status(): systemd_cmd("status") - sys.exit(0) \ No newline at end of file + sys.exit(0) diff --git a/fetch_cord/resources/terminal.json b/fetch_cord/resources/terminal.json new file mode 100644 index 0000000..0a0574c --- /dev/null +++ b/fetch_cord/resources/terminal.json @@ -0,0 +1,57 @@ +{ + "1207401167634698331": [ + "(?i)xfce4", + "(?i)xfce4-terminal" + ], + "741285676250824725": [ + "(?i)kitty" + ], + "741291339945345045": [ + "(?i)alacritty" + ], + "741287143187546125": [ + "(?i)xterm" + ], + "741286819676553258": [ + "(?i)konsole" + ], + "741328861115056160": [ + "(?i)gnome-terminal" + ], + "741731097498353794": [ + "(?i)cool-retro-term" + ], + "743246048968835092": [ + "(?i)urxvt" + ], + "744950796298354689": [ + "apple_terminal" + ], + "745701997503840380": [ + "lxterminal" + ], + "746531413360377856": [ + "(?i)mate-terminal" + ], + "878027718132899901": [ + "(?i)terminus", + "io.elementary.t" + ], + "878034077444374559": [ + "(?i)windows", + "(?i)ConsoleHost" + ], + "741280043220861030": [ + "st" + ], + "1207410925892800512": [ + "(?i)relay", + "(?i)wsl" + ], + "744332423072055296": [ + "(?i)terminal" + ], + "745691250186911796": [ + "unknown" + ] +} \ No newline at end of file diff --git a/fetch_cord/resources/windowmanager.json b/fetch_cord/resources/windowmanager.json new file mode 100644 index 0000000..6681af6 --- /dev/null +++ b/fetch_cord/resources/windowmanager.json @@ -0,0 +1,32 @@ +{ + "dwm": [ + "(?i)dwm" + ], + "i3": [ + "(?i)i3" + ], + "awesome": [ + "(?i)awesome" + ], + "enlightenment": [ + "(?i)enlightenment" + ], + "bspwm": [ + "(?i)bspwm" + ], + "xmonad": [ + "(?i)xmonad" + ], + "sway": [ + "(?i)sway" + ], + "openbox": [ + "(?i)openbox" + ], + "herbstluftwm": [ + "(?i)herbstluftwm" + ], + "unknown": [ + "unknown" + ] +} \ No newline at end of file diff --git a/fetch_cord/run_command.py b/fetch_cord/run_command.py deleted file mode 100755 index eb275d5..0000000 --- a/fetch_cord/run_command.py +++ /dev/null @@ -1,31 +0,0 @@ -#from __future__ import annotations - -from typing import List -import subprocess - - -def run_command(command: List[str], shell: bool = False): - return subprocess.run( - command, encoding="utf-8", stdout=subprocess.PIPE, shell=shell - ).stdout - - -class BashError(Exception): - pass - - -def exec_bash(command: str): - try: - out = ( - subprocess.check_output(["bash", "-c", command], stderr=subprocess.STDOUT) - .decode("utf8") - .strip() - ) - - except subprocess.CalledProcessError as e: - out = e.stdout.decode("utf8") - raise BashError("Failed to execute '%s' :\n%s" % (command, out)) - except FileNotFoundError as e: - raise BashError("BASH not installed on your computer...") - - return out diff --git a/fetch_cord/run_rpc.py b/fetch_cord/run_rpc.py deleted file mode 100755 index 72b5284..0000000 --- a/fetch_cord/run_rpc.py +++ /dev/null @@ -1,128 +0,0 @@ -#from __future__ import annotations - - -from typing import Callable, Dict -from pypresence import Presence, exceptions -import time, sys - -# import info about system -from .args import parse_args -from .config import ConfigError, load_config -from .computer.Computer import Computer - -args = parse_args() - - -class Run_rpc: - rpcs: Dict[str, Presence] - config: Dict - - loops: Dict[str, Callable[['Run_rpc', str, Computer], None]] # Cannot use Run_rpc for type hinting unless doing the __future__.annotations import - loops_indexes: Dict[int, str] - poll_rate: int - update: Callable - - def __init__(self): - self.rpcs = {} - - try: - self.config = load_config() - except ConfigError as e: - print("Error loading config file, using default values." % str(e)) - - def set_loop( - self, loops: Dict, loops_indexes: Dict, update: Callable, poll_rate: int = 3 - ): - self.loops = loops - self.loops_indexes = loops_indexes - - self.poll_rate = poll_rate - self.update = update - - def run_loop(self, computer: Computer): - try: - loop = 0 - while True: - for i in range(len(self.loops_indexes)): - if loop == self.poll_rate: - self.update() - loop = 0 - try: - client_id, func = self.loops[self.loops_indexes[i]] - - if args.debug: - print(self.rpcs) - print( - "{} not in : {}".format( - self.loops_indexes[i], - self.loops_indexes[i] not in self.rpcs, - ) - ) - if self.loops_indexes[i] not in self.rpcs: - self.rpcs[self.loops_indexes[i]] = Presence(client_id) - self.try_connect(self.loops_indexes[i]) - - func(self, self.loops_indexes[i], computer) - loop += 1 - except ConnectionResetError: - self.try_connect(self.loops_indexes[i]) - except KeyboardInterrupt: - print("Closing connection.") - sys.exit(0) - - def try_connect(self, key: str): - while True: - try: - if args.debug: - print('try_connect(key="{}") on {}'.format(key, self.rpcs[key])) - self.rpcs[key].connect() - break - except ConnectionRefusedError: - print( - "RPC connection refused (is Discord open?); trying again in 30 seconds" - ) - time.sleep(30) - - def try_clear(self, key: str): - # Pypresence clear doesn't work anymore - # try: - # if args.debug: - # print( - # "[key={}] try_clear(pid={} on {}".format( - # key, os.getpid(), self.rpcs[key] - # ) - # ) - # self.rpcs[key].clear(pid=os.getpid()) - # except exceptions.InvalidID: - # pass - # except exceptions.ServerError as e: - # print(e) - # pass - self.rpcs[key].close() - - def try_update( - self, - key: str, - state, - details, - large_image, - large_text, - small_image, - small_text, - start, - ): - try: - if args.debug: - print('try_update(key="{}") on {}'.format(key, self.rpcs[key])) - self.rpcs[key].update( - state=state, - details=details, - large_image=large_image, - large_text=large_text, - small_image=small_image, - small_text=small_text, - start=start, - ) - # ConnectionResetError is here to avoid crashing if Discord is still just starting - except (ConnectionResetError, exceptions.InvalidID): - pass \ No newline at end of file diff --git a/fetch_cord/update.py b/fetch_cord/update.py index 73c0599..8d8e0b0 100755 --- a/fetch_cord/update.py +++ b/fetch_cord/update.py @@ -1,13 +1,17 @@ -#from __future__ import annotations +# from __future__ import annotations -import urllib.request, sys, os -from .args import parse_args +import os +import sys +import urllib.request + +from fetch_cord.args import parse_args args = parse_args() + def update(): print("Updating database...") - url = f"https://raw.githubusercontent.com/MrPotatoBobx/FetchCord/{'testing' if args.testing else 'master'}/fetch_cord/resources/fetchcord_ids.json" + url = f"https://raw.githubusercontent.com/fetchcord/FetchCord/{'testing' if args.testing else 'master'}/fetch_cord/resources/fetchcord_ids.json" urllib.request.urlretrieve( url, os.path.dirname(__file__) + "/resources/fetchcord_ids.json" ) diff --git a/setup.py b/setup.py index 83c56c7..2e1c1f5 100755 --- a/setup.py +++ b/setup.py @@ -9,30 +9,33 @@ description="grabs information about your Distro and displays it as Discord Rich Presence.", long_description=open(join(dirname(__file__), "README.md")).read(), long_description_content_type="text/markdown", - url="https://github.com/MrPotatoBobx/FetchCord", - author="MrPotatoBobx", - author_email="junkahole23@protonmail.com", + url="https://github.com/fetchcord/FetchCord", + author="FetchCord team", + author_email="contact@fetchcord.org", license="MIT", package_data={ "fetch_cord": [ - "config_schema.json", + "resources/scripts/*", + "resources/scripts/*/*", + "resources/fetchcord_conf.yml", + "resources/fetchcord_cmds.yml", "resources/default.conf", - "resources/fetch_cord.conf", - "resources/fetchcord_ids.json", - "computer/*.py", - "computer/*/*.py", + "resources/*.py", + "native/*.py", + "native/*/*.py", + "resources/*.json", ] }, packages=["fetch_cord"], include_package_data=True, - install_requires=["pypresence", "psutil", "importlib-resources"], + install_requires=["pypresence", "psutil", "importlib-resources", "pyyaml"], keywords=["distro", "info", "discord", "fetch"], classifiers=[ "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", "Operating System :: OS Independent", ], - python_requires=">=3.6", + python_requires=">=3.7", entry_points={ "console_scripts": [ "fetchcord=fetch_cord.__main__:main", diff --git a/snapcraft.yaml b/snapcraft.yaml index c5bb304..a3a940c 100644 --- a/snapcraft.yaml +++ b/snapcraft.yaml @@ -13,12 +13,13 @@ parts: python-version: python3 source: . stage-packages: - - neofetch + - fastfetch python-packages: - pypresence - psutil - importlib-resources + - PyQt5 apps: fetchcord: - command: bin/fetchcord \ No newline at end of file + command: bin/fetchcord diff --git a/tests/test_fetch_cord_computer.py b/tests/test_fetch_cord_computer.py index 69ad494..d017b61 100755 --- a/tests/test_fetch_cord_computer.py +++ b/tests/test_fetch_cord_computer.py @@ -43,14 +43,14 @@ def test_detected_os(self): print("Detected OS : " + self.pc.os) @ordered - def test_detected_neofetch(self): - """Test detected neofetch""" - - print("Detected Neofetch : ", end="") - if self.pc.neofetch: - print("neofetch") - elif self.pc.neofetchwin: - print("neofetch-win") + def test_detected_fastfetch(self): + """Test detected fastfetch""" + + print("Detected fastfetch : ", end="") + if self.pc.fastfetch: + print("fastfetch") + # elif self.pc.neofetchwin: + # print("neofetch-win") else: print("None")