Skip to content

Commit

Permalink
Fetchcord 3.0: Simpler code, less neofetch dependency on windows (#227)
Browse files Browse the repository at this point in the history
* Add parrot OS  (#153)
* Add asrock motherboard support
* Fix future import bug and amd A series detection
* fix packaging
* Manifest stuff
* INtel gpu fix
* Add some acer mobo
* add optiplex (generic)
* Add snap support (#146)
* Create snapcraft.yml
* add snap support
* fix README
* fix windows scoop neofetch compatibility
* Add more mobo support and os's
* Add mageia
* Add elitedesk 800 g1
* Fix debug and add windows 11
* Add athlon silver & gold cpu support
* Prepare alt mobo detect
* Add some random acer laptop
* Add elementary os support and thinkcenter
* Disable logger
* Add terminus / elementary os terminal
* Add windows terminal
* Update README.md
* Baseline for v3
* flake8 and Cycle correction
* Adding kernel script
* Update Config.py
* MOre scripts
* Migrating jsons
* Motherboards json migration
* Minicrep
* Update os.json
* Fix unkown issues
* Improve regexes
* Add OS script for Macos and Linux + updated cpu list
* Add debug
* Remove scripts and use commands from config
* Remove lspci central db query option'
* Add better gpu detection for linux'
* Fix better gpu detection for macos'
* Add macos to the os list
* Improved terminal detection, gpu detection and cycle time config
* Fix potential issue on systems where python == python2
* Improve terminal detection
* Use custom config for neofetch
* Syntax cleanup
* Add native python query mode
* Linux specific fixes
Disable import of windows libs on non windows systems
Fix host/motherboard dection on linux
* Update Fetch.py
* Update setup.py
* Fix macos detection

---------

Co-authored-by: Tabulate <tabulatejarl8@gmail.com>
Co-authored-by: MelonMan <73000042+MelonicOverlord@users.noreply.github.com>
  • Loading branch information
3 people authored Apr 21, 2024
1 parent de98dee commit eb11bf1
Show file tree
Hide file tree
Showing 50 changed files with 997 additions and 1,961 deletions.
8 changes: 3 additions & 5 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
include *.py
include */*.py
include */*/*.py
include */*/FetchDis.png
include */*/*/*.py
include resources/*.json
include resources/fetchcord_conf.yml
include resources/default.conf
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,8 @@ default config path should be `~/.config/neofetch/config.conf`
-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 a work in progress though.

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

Expand All @@ -183,4 +184,4 @@ Fetchcord now has a website! You can find this site over at https://fetchcord.gi
![HP laptop](Examples/hp.png) ![TUF gaming laptop](Examples/tuf.png) ![Lenovo desktop](Examples/len.png)
### GUI
Note that the GUI version may look different depending on your OS and Qt theme.
![GUI](Examples/gui.png)
![GUI](Examples/gui.png)
26 changes: 26 additions & 0 deletions fetch_cord/Config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/usr/bin/env python3

from importlib import resources
import yaml


class Config(dict):
def __init__(self) -> None:
super(Config, self).__init__(
self.get_config(
self.get_resource_path("fetch_cord.resources", "fetchcord_conf.yml")
)
)

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
89 changes: 80 additions & 9 deletions fetch_cord/Cycle.py
Original file line number Diff line number Diff line change
@@ -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"]
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}}}"""
62 changes: 62 additions & 0 deletions fetch_cord/Fetch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#!/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

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:
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"
44 changes: 44 additions & 0 deletions fetch_cord/Tools.py
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion fetch_cord/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
VERSION = "2.7.8"
VERSION = "3.0.0"
Loading

0 comments on commit eb11bf1

Please sign in to comment.