From 74f4fe625b07749b3ca5f20b29918b080a699c34 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Thu, 8 Oct 2026 02:23:54 +0000 Subject: [PATCH 1/2] Trim comments that only repeat the next line Drop narration from the 3.0 rewrite that restates the following statement, and leave comments that explain why. Co-authored-by: BlivionIaG --- fetch_cord/__main__.py | 7 ------- fetch_cord/cycle.py | 3 --- fetch_cord/resources/fetchcord_cmds.yml | 17 ----------------- fetch_cord/resources/systemd_service.py | 17 ----------------- fetch_cord/tools.py | 4 ---- snapcraft.yaml | 3 +-- tests/test_fetch_cord.py | 25 ------------------------- 7 files changed, 1 insertion(+), 75 deletions(-) diff --git a/fetch_cord/__main__.py b/fetch_cord/__main__.py index 9c60d0b..764ac83 100755 --- a/fetch_cord/__main__.py +++ b/fetch_cord/__main__.py @@ -125,7 +125,6 @@ def main( args = parse_args() handle_args(args) - # Get the ids for the components fetchcord_ids = { "cpu": get_infos("cpus"), "gpu": get_infos("gpus"), @@ -136,14 +135,11 @@ def main( "system_type": get_infos("system_types"), } - # Stop event for the loop (injectable for tests) if stop_event is None: 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"]] # Apply CLI overrides: honor --debug / --time and drop disabled cycles. @@ -215,7 +211,6 @@ def signal_handler(signum: int, frame: object) -> None: signal(SIGINT, signal_handler) signal(SIGTERM, signal_handler) - # Main loop current_client_id = None while not stop_event.is_set(): if pause.check(): @@ -238,7 +233,6 @@ def signal_handler(signum: int, frame: object) -> None: # Windows a snapshot is a dozen PowerShell processes. snapshot = fetch.snapshot() - # Loop through the cycles defined in the config for cycle in cycles: if stop_event.is_set(): break @@ -275,7 +269,6 @@ def signal_handler(signum: int, frame: object) -> None: large_image: {large_image}""" ) - # Reconnect if client_id changed if client_id != current_client_id: # Close ALL cycles' connections since Discord only allows one RP at a time for c in cycles: diff --git a/fetch_cord/cycle.py b/fetch_cord/cycle.py index dd0c068..99bd3cc 100755 --- a/fetch_cord/cycle.py +++ b/fetch_cord/cycle.py @@ -60,7 +60,6 @@ def try_connect(self) -> None: self.wait(DEFAULT_CYCLE_TIME_SECONDS) def close_connection(self) -> None: - """Fully close the RPC connection and ensure cleanup.""" if self.rpc is not None: try: self.rpc.clear() @@ -107,14 +106,12 @@ def update( except ConnectionResetError as e: if self.debug: print(f'update: ConnectionResetError for "{self.name}": {e}') - # Connection was reset - need to reconnect self.close_connection() raise except exceptions.InvalidID as e: if self.debug: print(f'update: InvalidID for "{self.name}": {e}') - # Invalid client_id - need to re-setup with new client_id self.close_connection() raise diff --git a/fetch_cord/resources/fetchcord_cmds.yml b/fetch_cord/resources/fetchcord_cmds.yml index ebc17b6..b6f6636 100644 --- a/fetch_cord/resources/fetchcord_cmds.yml +++ b/fetch_cord/resources/fetchcord_cmds.yml @@ -16,58 +16,41 @@ commands: 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 MemAvailable | awk '{print $2}') - # Convert values to GB TotalMemory=$(awk "BEGIN {printf \"%.2f\", $TotalMemory / 1024 / 1024}") AvailableMemory=$(awk "BEGIN {printf \"%.2f\", $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 {printf \"%.2f\", $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: | diff --git a/fetch_cord/resources/systemd_service.py b/fetch_cord/resources/systemd_service.py index 6793a58..1e5c0ff 100644 --- a/fetch_cord/resources/systemd_service.py +++ b/fetch_cord/resources/systemd_service.py @@ -25,7 +25,6 @@ def validate_systemd_cmd(cmd: str) -> str: def get_systemd_user_dir() -> str: - """Get the systemd user directory path.""" home = os.path.expanduser("~") if not home or home == "~": raise ValueError("Unable to determine home directory") @@ -33,20 +32,11 @@ def get_systemd_user_dir() -> str: def get_service_file_url(testing: bool = False) -> str: - """Get the service file URL based on branch. - - Args: - testing: If True, use testing branch; otherwise use master. - - Returns: - The URL to download the service file from. - """ branch = TESTING_BRANCH if testing else DEFAULT_BRANCH return SERVICE_FILE_URL_TEMPLATE.format(branch=branch) def systemd_cmd(cmd: str) -> None: - """Execute a systemd command with validation.""" try: validated_cmd = validate_systemd_cmd(cmd) service_file = os.path.join(get_systemd_user_dir(), "fetchcord.service") @@ -61,7 +51,6 @@ def systemd_cmd(cmd: str) -> None: def install(testing: bool = False) -> None: - """Install the systemd service.""" systemd_dir = get_systemd_user_dir() try: @@ -84,7 +73,6 @@ def install(testing: bool = False) -> None: def uninstall() -> None: - """Uninstall the systemd service.""" systemd_cmd("stop") systemd_cmd("disable") @@ -101,30 +89,25 @@ def uninstall() -> None: def enable() -> None: - """Enable the systemd service.""" systemd_cmd("enable") sys.exit(0) def disable() -> None: - """Disable the systemd service.""" systemd_cmd("disable") sys.exit(0) def start() -> None: - """Start the systemd service.""" systemd_cmd("start") sys.exit(0) def stop() -> None: - """Stop the systemd service.""" systemd_cmd("stop") sys.exit(0) def status() -> None: - """Check the systemd service status.""" systemd_cmd("status") sys.exit(0) diff --git a/fetch_cord/tools.py b/fetch_cord/tools.py index 99db736..f663f6b 100644 --- a/fetch_cord/tools.py +++ b/fetch_cord/tools.py @@ -1,6 +1,5 @@ #!/usr/bin/env python3 -# trunk-ignore(bandit/B404) import subprocess from importlib import resources from pathlib import Path @@ -39,7 +38,6 @@ def exec_bash(command: str) -> str: # diagnostics, never a field value. capture_output=True, timeout=COMMAND_TIMEOUT_SECONDS, - # trunk-ignore(bandit/B602) shell=True, ) except subprocess.TimeoutExpired as exc: @@ -60,8 +58,6 @@ def exec_bash(command: str) -> str: def exec_ps1(command: str) -> str: - # trunk-ignore(bandit/B603) - # trunk-ignore(bandit/B607) try: result = subprocess.run( [ diff --git a/snapcraft.yaml b/snapcraft.yaml index 56b4640..c36b41a 100644 --- a/snapcraft.yaml +++ b/snapcraft.yaml @@ -5,8 +5,7 @@ grade: devel description: | FetchCord grabs your OS info and displays it as Discord Rich Presence. - The Snap package is unmaintained for 3.0 (classic confinement + core18 - cannot ship Python 3.12). Prefer pip or Homebrew. This file is kept so + Prefer pip or Homebrew. This file is kept so existing snap listings do not break the repo layout. base: core24 confinement: classic diff --git a/tests/test_fetch_cord.py b/tests/test_fetch_cord.py index 0bc7a4c..67f1178 100644 --- a/tests/test_fetch_cord.py +++ b/tests/test_fetch_cord.py @@ -21,13 +21,11 @@ class TestConfig(unittest.TestCase): - """Test cases for Config class.""" @patch("fetch_cord.config.get_resource_path", return_value="/fake/path/config.yml") @patch("fetch_cord.config.yaml.safe_load") @patch("builtins.open", new_callable=mock_open, read_data="key: value") def test_config_loads_yaml(self, mock_file, mock_yaml_load, mock_resources_path): - """Test that Config loads YAML configuration correctly.""" mock_resources_path.return_value = "/fake/path/config.yml" mock_yaml_load.return_value = {"key": "value", "nested": {"data": 123}} @@ -44,7 +42,6 @@ def test_config_loads_yaml(self, mock_file, mock_yaml_load, mock_resources_path) def test_config_acts_like_dict( self, mock_file, mock_yaml_load, mock_resources_path ): - """Test that Config behaves like a dictionary.""" mock_resources_path.return_value = "/fake/path/config.yml" mock_yaml_load.return_value = {"key": "value", "number": 42} @@ -62,7 +59,6 @@ def test_config_acts_like_dict( def test_config_default_config_name( self, mock_file, mock_yaml_load, mock_resources_path ): - """Test that Config uses default config name when not specified.""" mock_resources_path.return_value = "/fake/path/config.yml" mock_yaml_load.return_value = {"test": "data"} @@ -80,7 +76,6 @@ def test_config_default_config_name( def test_config_yaml_error_handling( self, mock_file, mock_print, mock_resources_path ): - """Test that Config handles YAML errors gracefully.""" import yaml mock_resources_path.return_value = "/fake/path/config.yml" @@ -95,10 +90,8 @@ def test_config_yaml_error_handling( class TestCycle(unittest.TestCase): - """Test cases for Cycle class.""" def setUp(self): - """Set up test fixtures.""" self.config = { "name": "test_cycle", "app_id": "123456789", @@ -111,7 +104,6 @@ def setUp(self): @patch("fetch_cord.cycle.Presence") def test_cycle_initialization(self, mock_presence_class): - """Test Cycle initialization with config.""" from fetch_cord.cycle import Cycle stop_event = Event() @@ -128,7 +120,6 @@ def test_cycle_initialization(self, mock_presence_class): @patch("fetch_cord.cycle.Presence") def test_cycle_default_stop_event(self, mock_presence_class): - """Test Cycle creates default stop event if none provided.""" from fetch_cord.cycle import Cycle cycle = Cycle(self.config) @@ -138,7 +129,6 @@ def test_cycle_default_stop_event(self, mock_presence_class): @patch("fetch_cord.cycle.Presence") def test_cycle_setup(self, mock_presence_class): - """Test Cycle setup method.""" mock_presence = MagicMock() mock_presence_class.return_value = mock_presence @@ -152,7 +142,6 @@ def test_cycle_setup(self, mock_presence_class): @patch("fetch_cord.cycle.Presence") def test_cycle_try_connect_success(self, mock_presence_class): - """Test Cycle try_connect succeeds immediately.""" mock_presence = MagicMock() mock_presence.connect = MagicMock() mock_presence_class.return_value = mock_presence @@ -168,7 +157,6 @@ def test_cycle_try_connect_success(self, mock_presence_class): @patch("fetch_cord.cycle.Presence") @patch("fetch_cord.cycle.print") def test_cycle_try_connect_refused(self, mock_print, mock_presence_class): - """Test Cycle try_connect handles ConnectionRefusedError.""" mock_presence = MagicMock() mock_presence.connect.side_effect = [ ConnectionRefusedError(), @@ -190,7 +178,6 @@ def test_cycle_try_connect_refused(self, mock_print, mock_presence_class): @patch("fetch_cord.cycle.psutil") @patch("fetch_cord.cycle.Presence") def test_cycle_update(self, mock_presence_class, mock_psutil): - """Test Cycle update method.""" mock_presence = MagicMock() mock_presence.update = MagicMock() mock_presence.close = MagicMock() @@ -219,7 +206,6 @@ def test_cycle_update(self, mock_presence_class, mock_psutil): @patch("fetch_cord.cycle.Presence") def test_cycle_wait(self, mock_presence_class): - """Test Cycle wait method.""" from fetch_cord.cycle import Cycle stop_event = Event() @@ -272,7 +258,6 @@ def test_cycle_wait_returns_promptly_when_stopped(self, mock_presence_class): @patch("fetch_cord.cycle.Presence") def test_cycle_repr(self, mock_presence_class): - """Test Cycle __repr__ method.""" from fetch_cord.cycle import Cycle cycle = Cycle(self.config) @@ -307,7 +292,6 @@ class TestFetchFunctions(unittest.TestCase): """Test cases for Fetch module functions (standalone, no module imports).""" def test_get_component_id_exact_match(self): - """Test get_component_id with exact pattern match.""" id_list = { "intel_cpu": ["Intel.*i7", "Intel.*i5"], "amd_cpu": ["AMD.*Ryzen", "AMD.*FX"], @@ -317,7 +301,6 @@ def test_get_component_id_exact_match(self): self.assertEqual(result, "intel_cpu") def test_get_component_id_no_match_with_unknown(self): - """Test get_component_id returns unknown when no match.""" id_list = { "intel_cpu": ["Intel.*i7"], "amd_cpu": ["AMD.*Ryzen"], @@ -328,7 +311,6 @@ def test_get_component_id_no_match_with_unknown(self): self.assertEqual(result, "unknown") def test_get_component_id_no_match_no_unknown(self): - """Test get_component_id returns 'unknown' string when no match and no unknown pattern.""" id_list = { "intel_cpu": ["Intel.*i7"], } @@ -337,7 +319,6 @@ def test_get_component_id_no_match_no_unknown(self): self.assertEqual(result, "unknown") def test_get_component_id_case_sensitive(self): - """Test get_component_id with case sensitivity.""" id_list = { "intel_cpu": ["Intel"], } @@ -591,11 +572,9 @@ def test_fastfetch_drops_pythonish_terminal(self, mock_run): class TestTools(unittest.TestCase): - """Test cases for Tools module.""" @patch("fetch_cord.tools.subprocess.run") def test_run_command(self, mock_run): - """Test run_command function.""" mock_process = MagicMock() mock_process.stdout = "command output" mock_run.return_value = mock_process @@ -638,7 +617,6 @@ def test_run_command_with_shell(self, mock_run): @patch("fetch_cord.tools.subprocess.run") def test_exec_bash(self, mock_run): - """Test exec_bash function.""" mock_process = MagicMock() mock_process.stdout = " bash output \n" mock_process.returncode = 0 @@ -672,7 +650,6 @@ def test_exec_bash_raises_on_failure(self, mock_run): @patch("fetch_cord.tools.subprocess.run") def test_exec_ps1(self, mock_run): - """Test exec_ps1 function.""" mock_process = MagicMock() mock_process.stdout = " powershell output \n" mock_process.returncode = 0 @@ -793,7 +770,6 @@ def test_run_command_timeout_raises_bash_error(self, mock_run): @patch("fetch_cord.tools.resources.path") def test_get_resource_path(self, mock_resources_path): - """Test get_resource_path function.""" mock_path = MagicMock() mock_path.__enter__ = MagicMock(return_value="/fake/path") mock_path.__exit__ = MagicMock(return_value=False) @@ -807,7 +783,6 @@ def test_get_resource_path(self, mock_resources_path): self.assertEqual(result, "/fake/path") def test_bash_error_exception(self): - """Test BashError exception can be raised.""" from fetch_cord.tools import BashError with self.assertRaises(BashError): From 697168b1f6a21439a0fb3f42993b234c4497c117 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Thu, 8 Oct 2026 02:25:11 +0000 Subject: [PATCH 2/2] Drop blank lines left under deleted class docstrings Ruff format rejects the empty line that used to separate a class docstring from the first method. Co-authored-by: BlivionIaG --- tests/test_fetch_cord.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/test_fetch_cord.py b/tests/test_fetch_cord.py index 67f1178..fe4a770 100644 --- a/tests/test_fetch_cord.py +++ b/tests/test_fetch_cord.py @@ -21,7 +21,6 @@ class TestConfig(unittest.TestCase): - @patch("fetch_cord.config.get_resource_path", return_value="/fake/path/config.yml") @patch("fetch_cord.config.yaml.safe_load") @patch("builtins.open", new_callable=mock_open, read_data="key: value") @@ -90,7 +89,6 @@ def test_config_yaml_error_handling( class TestCycle(unittest.TestCase): - def setUp(self): self.config = { "name": "test_cycle", @@ -572,7 +570,6 @@ def test_fastfetch_drops_pythonish_terminal(self, mock_run): class TestTools(unittest.TestCase): - @patch("fetch_cord.tools.subprocess.run") def test_run_command(self, mock_run): mock_process = MagicMock()