209 lines
14 KiB
Markdown
209 lines
14 KiB
Markdown
|
|
# Автоматическая смена статуса в мессенджере
|
|||
|
|
|
|||
|
|
Скрипт запускается вместе с ОС, проверяет 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.0–1.0 от размера окна.
|
|||
|
|
- **image_confidence** (опционально) — порог совпадения при поиске по картинке (0.0–1.0, по умолчанию 0.8). Чем выше, тем строже совпадение.
|
|||
|
|
|
|||
|
|
### Поиск по картинкам (разные разрешения)
|
|||
|
|
|
|||
|
|
Сделайте скриншоты элементов интерфейса (иконка/аватар для открытия меню, поле статуса, кнопка «Сохранить»), сохраните в папку `images/` и укажите в `_app`:
|
|||
|
|
|
|||
|
|
- **icon_image**: `"images/icon.png"`
|
|||
|
|
- **status_image**: `"images/status.png"`
|
|||
|
|
- **save_button_image**: `"images/save.png"`
|
|||
|
|
|
|||
|
|
Картинки должны быть небольшими фрагментами (например 40×40–80×80 пикселей), без лишнего фона. Скрипт ищет их на экране и кликает в центр — один конфиг работает на любом разрешении и масштабе. При необходимости понизьте **image_confidence** (например 0.7), если совпадение не находится.
|
|||
|
|
|
|||
|
|
### Координаты в долях (альтернатива картинкам)
|
|||
|
|
|
|||
|
|
Чтобы один конфиг работал на разных разрешениях без картинок, задайте координаты **относительно окна** в долях 0–1 в полях `*_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, одна команда | Размер 50–150 МБ |
|
|||
|
|
| **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) — при запуске окно консоли не появляется. Размер порядка 80–150 МБ.
|
|||
|
|
|
|||
|
|
### Запуск собранного exe
|
|||
|
|
|
|||
|
|
- Рядом с исполняемым файлом должны лежать:
|
|||
|
|
- **config.json** — конфигурация (скопируйте из проекта или создайте по образцу).
|
|||
|
|
- Папка **images/** с файлами icon.png, status.png, save.png (если используется поиск по картинкам).
|
|||
|
|
- Лог пишется в **status_automation.log** в той же папке.
|
|||
|
|
- На целевой машине **Python и библиотеки устанавливать не нужно**; на Linux для управления окнами по‑прежнему нужен **wmctrl** (`sudo apt install wmctrl`).
|