make_icon() грузит PNG из icons/ по состоянию (серый/жёлтый/зелёный — цвета прежние) и кэширует. Если файла нет или он битый — прежняя отрисовка кружка. В .gitignore исключение для icons/*.png, иначе иконки не попадали в репозиторий под общим правилом *.png. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
VPN с TOTP-аутентификацией и индикатором в трее
Запуск
- Установить зависимости:
pip install pyotp keyring pystray pillow - Узнать имя сетевого адаптера:
bash show_tuns.sh— вписать имя (выводится до GUID) в.ovpn-профиль в строку послеdev tun. - Создать конфиг: скопировать
vpn_config.example.json→vpn_config.jsonи указать свои значения (username, путиovpn_config/openvpn_bin,ping_host— IP сервера для проверки связи). Если пропустить — файл создастся с дефолтами при первом запуске. - Расшифровать QR, вынуть
secret. - Положить секреты в keyring:
bash init.sh <secret> <static_pass>. - Запуск:
python launch_vpn_gui.py(запросит права администратора).
Ярлык без окна консоли — launch_vpn.bat: ищет pythonw.exe сначала в .venv проекта, затем в PATH, затем через pyw.exe -3.
Автозапуск при входе в систему
Через Планировщик заданий, а не папку «Автозагрузка»: оттуда процесс стартует непривилегированным, и ensure_admin() дёргает UAC-окно при каждом входе. Задача с «Запускать с наивысшими правами» отдаёт админский токен сразу — промпта нет.
Регистрация (один раз, нужен админ):
schtasks /create /tn VPN-TOTP-Tray /xml vpn_tray_task.xml /f
vpn_tray_task.xml лежит в корне репозитория (в UTF-16 — этого требует schtasks /xml). Пути к launch_vpn.bat и имя пользователя в нём захардкожены абсолютными — при переносе проекта или на другой машине правь <Arguments>, <WorkingDirectory> и оба <UserId>.
Управление:
schtasks /query /tn VPN-TOTP-Tray /v /fo list # статус
schtasks /run /tn VPN-TOTP-Tray # запустить сейчас
schtasks /change /tn VPN-TOTP-Tray /disable # временно выключить автозапуск
schtasks /delete /tn VPN-TOTP-Tray /f # снести (нужен админ)
Или через GUI: taskschd.msc → Библиотека планировщика → VPN-TOTP-Tray.
Индикатор в трее
- 🔘 серый — openvpn не запущен;
- 🟡 жёлтый — запущен, но пинги до
ping_hostне проходят; - 🟢 зелёный — запущен, связь с сервером есть.
Проверку связи можно отключить ("ping_check_enabled": false) — тогда только серый/зелёный.
Картинки берутся из icons/ (v-gray-256.png, v-yellow-256.png, v-green-256.png). Если файла нет — рисуется кружок того же цвета.
Настройки (vpn_config.json)
Правятся вручную или через пункт меню «Открыть настройки»; перечитываются на лету.
Секреты (secret, static) в конфиге не хранятся — они в keyring под именем keyring_service.