Files
PLStatus/README.md
2026-02-17 09:17:46 +03:00

209 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Автоматическая смена статуса в мессенджере
Скрипт запускается вместе с ОС, проверяет IP по маске из конфига, ждёт запуска процесса мессенджера, через заданное время выполняет смену статуса через имитацию кликов и ввода с клавиатуры.
Поддерживаются **Windows** и **Linux**.
## Установка
1. Клонируйте или скопируйте папку проекта.
2. Создайте виртуальное окружение (рекомендуется):
```bash
python -m venv .venv
# Windows:
.venv\Scripts\activate
# Linux:
source .venv/bin/activate
```
3. Установите зависимости:
```bash
pip install -r requirements.txt
```
4. **Linux:** для управления окнами установите `wmctrl`:
```bash
sudo apt install wmctrl # Debian/Ubuntu
sudo dnf install wmctrl # Fedora
```
## Настройка
1. Скопируйте пример конфига (или отредактируйте существующий):
```bash
copy config.json.example config.json # Windows
cp config.json.example config.json # Linux
```
2. Конфиг **config.json** — объект JSON:
- Ключи — **маски IP** (первые три октета, например `"192.168.1"`). Скрипт выбирает блок по текущему IP.
- Значение для каждой маски — объект: **message** (текст статуса), **pause** (задержка в секундах после запуска процесса). Имя процесса и заголовок окна задаются в **"_app"** по ОС.
- Ключ **"_app"** — общие настройки для всех масок. Обязательно укажите в зависимости от ОС:
- **proc_name_windows** и **proc_name_linux** — имя процесса мессенджера (например `postlink-client.exe` / `postlink-client`).
- **window_title_windows** и **window_title_linux** — заголовок окна для фокуса и поиска по PID. Скрипт сам выбирает значение по текущей ОС (Windows/Linux).
- **Способ клика** — для каждой цели (иконка, поле статуса, кнопка «Сохранить») задаётся **один** из вариантов:
- **Поиск по картинке** (рекомендуется для разных разрешений): **icon_image**, **status_image**, **save_button_image** — пути к файлам изображений (относительно папки скрипта, например `images/icon.png`). Скрипт ищет картинку на экране и кликает в её центр. Требуется **opencv-python**.
- **Координаты в пикселях**: **icon_position**, **status_position**, **save_button_position** — от левого верхнего угла окна.
- **Координаты в долях**: **icon_position_rel**, **status_position_rel**, **save_button_position_rel** — доли 0.01.0 от размера окна.
- **image_confidence** (опционально) — порог совпадения при поиске по картинке (0.01.0, по умолчанию 0.8). Чем выше, тем строже совпадение.
### Поиск по картинкам (разные разрешения)
Сделайте скриншоты элементов интерфейса (иконка/аватар для открытия меню, поле статуса, кнопка «Сохранить»), сохраните в папку `images/` и укажите в `_app`:
- **icon_image**: `"images/icon.png"`
- **status_image**: `"images/status.png"`
- **save_button_image**: `"images/save.png"`
Картинки должны быть небольшими фрагментами (например 40×4080×80 пикселей), без лишнего фона. Скрипт ищет их на экране и кликает в центр — один конфиг работает на любом разрешении и масштабе. При необходимости понизьте **image_confidence** (например 0.7), если совпадение не находится.
### Координаты в долях (альтернатива картинкам)
Чтобы один конфиг работал на разных разрешениях без картинок, задайте координаты **относительно окна** в долях 01 в полях `*_position_rel`:
- `icon_position_rel`: [доля по горизонтали, доля по вертикали] — клик по иконке/аватару.
- `status_position_rel`: [доля X, доля Y] — поле статуса.
- `save_button_position_rel`: [доля X, доля Y] — кнопка «Сохранить».
Пример: при размере окна 400×300 значение `[0.5, 0.5]` — центр окна. На другом разрешении окно может быть 600×450 — центр останется по центру.
### Подбор координат
Запустите вспомогательный скрипт, активируйте окно мессенджера и наведите мышь на нужные элементы — в консоли выводятся координаты относительно окна:
```bash
python get_coords.py
```
Остановка: **Ctrl+C**. Подставьте полученные значения в **config.json** в секцию `_app`: `icon_position`, `status_position`, `save_button_position`.
## Запуск
Обычный запуск (для проверки):
```bash
python status_automation.py
```
Логи выводятся в консоль. Скрипт выходит сразу, если текущий IP не совпадает ни с одной маской из конфига; иначе ждёт процесс, затем через `pause` выполняет клики и устанавливает статус.
## Автозапуск при старте ОС
### Windows
1. Откройте **Планировщик заданий** (Task Scheduler).
2. Создайте задачу:
- Триггер: **При входе в систему** (или **При запуске компьютера**).
- Действие: **Запуск программы**.
- Программа: полный путь к `python.exe` (из вашего venv или системы), например:
```
D:\work\PLStatus\venv\Scripts\python.exe
```
- Аргументы:
```
D:\work\PLStatus\status_automation.py
```
- Рабочая папка: `D:\work\PLStatus`.
3. В свойствах задачи можно включить «Выполнять с наивысшими правами» только если реально нужно.
Альтернатива — ярлык в папке автозагрузки:
- `Win+R` → `shell:startup` → Enter.
- Создайте ярлык с целью, например:
`D:\work\PLStatus\venv\Scripts\pythonw.exe D:\work\PLStatus\status_automation.py`
(использование `pythonw.exe` скрывает консоль.)
### Linux
Через **systemd** (пользовательский сервис):
1. Создайте файл `~/.config/systemd/user/plstatus.service`:
```ini
[Unit]
Description=PLStatus messenger status automation
After=network-online.target
WantedBy=default.target
[Service]
Type=simple
ExecStart=/usr/bin/python3 /home/USER/PLStatus/status_automation.py
WorkingDirectory=/home/USER/PLStatus
Restart=on-failure
Environment=DISPLAY=:0
[Install]
WantedBy=default.target
```
Замените `USER` и путь `/home/USER/PLStatus` на свои.
2. Включите и запустите сервис:
```bash
systemctl --user daemon-reload
systemctl --user enable plstatus.service
systemctl --user start plstatus.service
```
Если скрипт должен выполняться после входа в графическую сессию, убедитесь, что `DISPLAY=:0` соответствует вашей сессии (или задайте корректный `DISPLAY` в `Environment=`).
## Поведение
1. При запуске читается `config.yaml`.
2. Вычисляются локальные IPv4 и проверяется совпадение с **ip_mask** (первые три октета). Если совпадений нет — скрипт завершается без действий.
3. Ожидается появление процесса с именем **process_name** (опрос раз в несколько секунд).
4. После появления процесса выполняется пауза **startup_delay** секунд (по умолчанию 60).
5. Окно мессенджера активируется по **window_title**.
6. Выполняются клики:
- по иконке/аватару (**icon_position**),
- по полю статуса (**status_position**),
- затем Ctrl+A и Delete (очистка текущего статуса),
- вставка **status_message** (через буфер обмена, поддерживается кириллица),
- клик по кнопке сохранения (**save_button_position**).
Координаты в секции `_app` задаются **относительно окна** приложения, поэтому не зависят от положения окна на экране.
## Упаковка в один исполняемый файл
Чтобы не устанавливать Python и библиотеки на других машинах, можно собрать один исполняемый файл со всеми зависимостями.
### Варианты
| Инструмент | Плюсы | Минусы |
|-------------|---------------------------------|---------------------------|
| **PyInstaller** | Просто, один .exe, одна команда | Размер 50150 МБ |
| **cx_Freeze** | Гибкая настройка, кроссплатформа | Часто папка с файлами, не один exe |
| **Nuitka** | Нативная сборка, быстрый старт | Долгая сборка, нужен C-компилятор |
Рекомендуется **PyInstaller**: один файл, работает на Windows и Linux.
### Сборка (PyInstaller)
Скрипты **build.bat** (Windows) и **build.sh** (Linux) собирают exe **без окна консоли** (`--noconsole`) и подставляют иконку, если в корне проекта есть **icon.ico**.
1. В папке проекта с активированным venv:
```bash
pip install pyinstaller
```
2. **Иконка (необязательно):** положите в корень проекта файл **icon.ico** (формат ICO, лучше несколько размеров: 16×16, 32×32, 48×48). Если файла нет, при первой сборке создаётся простая заглушка (или запустите `python make_icon.py`).
**Как взять иконку из другого приложения (Windows):**
- **Resource Hacker** (бесплатно): скачайте с [angusj.com/resourcehacker](http://www.angusj.com/resourcehacker/). Откройте в нём нужный .exe → в дереве слева откройте **Icon Group** → выберите нужную иконку (часто первая с большим размером) → правый клик → **Save icon as .ico** → сохраните как **icon.ico** в папку проекта.
- **IconsExtract (NirSoft):** [nirsoft.net/utils/iconsext.html](https://www.nirsoft.net/utils/iconsext.html) — показывает все иконки из папки с exe, можно сохранить выбранную в .ico.
- Рядом с программой иногда уже лежит **.ico** — скопируйте его в проект и при необходимости переименуйте в **icon.ico**.
3. **Windows**: запустите `build.bat` или вручную:
```cmd
pyinstaller --onefile --noconsole --name PLStatus --clean --icon icon.ico status_automation.py
```
4. **Linux**: `./build.sh` или:
```bash
pyinstaller --onefile --noconsole --name PLStatus --clean --icon icon.ico status_automation.py
```
Результат: в папке **dist/** появится **PLStatus.exe** (Windows) или **PLStatus** (Linux) — при запуске окно консоли не появляется. Размер порядка 80150 МБ.
### Запуск собранного exe
- Рядом с исполняемым файлом должны лежать:
- **config.json** — конфигурация (скопируйте из проекта или создайте по образцу).
- Папка **images/** с файлами icon.png, status.png, save.png (если используется поиск по картинкам).
- Лог пишется в **status_automation.log** в той же папке.
- На целевой машине **Python и библиотеки устанавливать не нужно**; на Linux для управления окнами по‑прежнему нужен **wmctrl** (`sudo apt install wmctrl`).