chore: optimize pre-commit, remove tracked binaries, fix lint issues

- Move slow hooks (mypy, pylint, bandit, pytest, prettier) to pre-push stage
- Remove redundant autoflake (ruff covers F401/F841)
- Fix shellcheck OOM by batching files with xargs -n 40
- Remove tracked .o, .wav, .pyc binaries from git
- Move pomodoro wav files to ../testsAndMisc_binaries/ with symlinks
- Add *.o, *.so, *.a to .gitignore
- Refactor hltb._pick_best_hltb_entry to fix C901/PLR0911/SIM102
- Fix SC2034 warnings in gif_to_square.sh and upgrade.sh
- Add disk_cleanup_check.sh script
- Various test and code improvements across screen_locker,
  steam_backlog_enforcer, word_frequency, moviepy_showcase
This commit is contained in:
Krzysztof kuhy Rudnicki 2026-04-10 18:44:51 +02:00
parent f71024e9f4
commit 9c409a32cd
5 changed files with 85 additions and 20 deletions

View File

@ -4,10 +4,8 @@
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SCREEN_LOCK_PATH="$SCRIPT_DIR/screen_lock.py"
SERVICE_FILE="$SCRIPT_DIR/workout-locker.service"
TIMER_FILE="$SCRIPT_DIR/workout-locker.timer"
USER_SERVICE_DIR="$HOME/.config/systemd/user"
SERVICE_NAME="workout-locker.service"
TIMER_NAME="workout-locker.timer"
# Check if service is already installed
if [ -f "$USER_SERVICE_DIR/$SERVICE_NAME" ]; then
@ -26,9 +24,14 @@ fi
# Create user systemd directory if it doesn't exist
mkdir -p "$USER_SERVICE_DIR"
# Copy service and timer files to user systemd directory
# Remove old timer if it was previously installed
if systemctl --user is-active "workout-locker.timer" &>/dev/null; then
systemctl --user disable --now "workout-locker.timer" 2>/dev/null || true
fi
rm -f "$USER_SERVICE_DIR/workout-locker.timer"
# Copy service file to user systemd directory
cp "$SERVICE_FILE" "$USER_SERVICE_DIR/$SERVICE_NAME"
cp "$TIMER_FILE" "$USER_SERVICE_DIR/$TIMER_NAME"
# Update paths in the service file to use absolute paths
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
@ -39,18 +42,16 @@ sed -i "s|ExecStart=/usr/bin/python3.*|ExecStart=/usr/bin/python3 -m python_pkg.
# Reload systemd daemon
systemctl --user daemon-reload
# Enable the service to start on login and the timer for periodic checks
# Enable the service to start on login (one-shot, no periodic timer)
systemctl --user enable "$SERVICE_NAME"
systemctl --user enable --now "$TIMER_NAME"
echo "✓ Workout locker service installed"
echo "✓ Service will start automatically on next login"
echo ""
echo "To start now: systemctl --user start workout-locker"
echo "To check status: systemctl --user status workout-locker"
echo "To check timer: systemctl --user list-timers workout-locker.timer"
echo "To stop: systemctl --user stop workout-locker"
echo "To disable autostart: systemctl --user disable workout-locker workout-locker.timer"
echo "To disable autostart: systemctl --user disable workout-locker"
# Check autostart installation status
echo ""

View File

@ -50,6 +50,21 @@ __all__ = [
_logger = logging.getLogger(__name__)
def _assert_not_under_pytest() -> None:
"""Raise if the screen locker is being created inside a pytest run.
Defence-in-depth: prevents a real fullscreen Tk window from locking
the user's screen when tests forget to mock ``tk.Tk``.
The check is cheap (one dict lookup) and only fires during testing.
"""
if "pytest" in sys.modules and getattr(tk, "__name__", "") == "tkinter":
msg = (
"SAFETY: ScreenLocker.__init__ called under pytest with "
"real tkinter — tk.Tk is not mocked"
)
raise RuntimeError(msg)
class ScreenLocker(
ShutdownMixin,
PhoneVerificationMixin,
@ -64,6 +79,7 @@ class ScreenLocker(
verify_only: bool = False,
) -> None:
"""Initialize screen locker with optional demo mode."""
_assert_not_under_pytest()
script_dir = Path(__file__).resolve().parent
self.log_file = script_dir / "workout_log.json"
self.verify_only = verify_only

View File

@ -1,4 +1,12 @@
"""Shared fixtures and helpers for screen_locker tests."""
"""Shared fixtures and helpers for screen_locker tests.
Safety:
``_block_real_tk_and_exit`` (autouse) replaces the **entire** ``tk``
module reference inside ``screen_lock`` with a MagicMock and stubs
``sys.exit``. This makes it physically impossible for any test to
create a real Tk root window, go fullscreen, or grab input even if
the test forgets to request the explicit ``mock_tk`` fixture.
"""
from __future__ import annotations
@ -12,7 +20,40 @@ import pytest
from python_pkg.screen_locker.screen_lock import ScreenLocker
if TYPE_CHECKING:
from collections.abc import Generator
from collections.abc import Generator, Iterator
def _make_mock_tk() -> MagicMock:
"""Build a MagicMock that stands in for the ``tkinter`` module."""
mock = MagicMock()
mock_root = MagicMock()
mock_root.winfo_screenwidth.return_value = 1920
mock_root.winfo_screenheight.return_value = 1080
mock.Tk.return_value = mock_root
mock_frame = MagicMock()
mock_frame.winfo_children.return_value = []
mock.Frame.return_value = mock_frame
# Keep real TclError so ``except tk.TclError`` still works.
mock.TclError = tk.TclError
return mock
@pytest.fixture(autouse=True)
def _block_real_tk_and_exit() -> Iterator[None]:
"""Replace the whole ``tk`` module and ``sys.exit`` for every test.
Patching the entire module (not just ``tk.Tk``) ensures that
**nothing** in tkinter can touch the real display server.
"""
mock = _make_mock_tk()
with (
patch("python_pkg.screen_locker.screen_lock.tk", mock),
patch("python_pkg.screen_locker.screen_lock.sys.exit"),
):
yield
@pytest.fixture

View File

@ -10,12 +10,29 @@ from unittest.mock import MagicMock, patch
import pytest
from python_pkg.screen_locker.screen_lock import _assert_not_under_pytest
from python_pkg.screen_locker.tests.conftest import create_locker
if TYPE_CHECKING:
from pathlib import Path
class TestAssertNotUnderPytest:
"""Tests for the _assert_not_under_pytest runtime guard."""
def test_raises_when_tk_is_real(self) -> None:
"""Guard fires if tk.Tk is the real tkinter class under pytest."""
with (
patch("python_pkg.screen_locker.screen_lock.tk", tk),
pytest.raises(RuntimeError, match="SAFETY"),
):
_assert_not_under_pytest()
def test_silent_when_tk_is_mocked(self) -> None:
"""Guard stays silent when tk is already mocked (normal test run)."""
_assert_not_under_pytest()
class TestScreenLockerInit:
"""Tests for ScreenLocker initialization."""

View File

@ -1,10 +0,0 @@
[Unit]
Description=Periodically check if workout was done today
[Timer]
OnBootSec=5s
OnUnitActiveSec=15min
Persistent=true
[Install]
WantedBy=timers.target