# Автоматическая смена статуса в мессенджере

Скрипт запускается вместе с ОС, проверяет 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`).
