# Major Scraper — руководство пользователя

Приложение для автоматического мониторинга каталога [major-expert.ru](https://www.major-expert.ru/cars/all/). Работает в трее Windows, периодически собирает новые/обновлённые объявления и присылает отчёт на почту.

---

## Содержание

- [Установка и первый запуск](#установка-и-первый-запуск)
- [Меню трея](#меню-трея)
- [Настройки](#настройки)
  - [Вкладка «Сканирование»](#вкладка-сканирование)
  - [Вкладка «Поля»](#вкладка-поля)
  - [Вкладка «API»](#вкладка-api)
  - [Вкладка «Почта»](#вкладка-почта)
- [Цвет иконки в трее](#цвет-иконки-в-трее)
- [Хранение данных](#хранение-данных)
- [Несколько копий приложения](#несколько-копий-приложения)
- [Отчёты об ошибках](#отчёты-об-ошибках)
- [Решение проблем](#решение-проблем)

---

## Установка и первый запуск

1. Распакуй архив `MajorScraper.zip` в любую папку (например, `C:\Apps\MajorScraper\`).
2. Запусти `MajorScraper.exe`. Окно не появится — приложение свернётся в трей рядом с часами (значок «M»).
3. Кликни правой кнопкой по значку — откроется меню. Сейчас расписание остановлено: статус **stopped**.
4. Выбери **Настройки…** и заполни параметры почты (см. [Вкладка «Почта»](#вкладка-почта)). Без этого отчёты не уйдут.
5. Когда настройки сохранены — выбери **Запустить расписание**. Через ~3 секунды стартует первый цикл.

> Приложение пишет данные в `%APPDATA%\major-scraper\<install-id>\` — каждая копия хранит свои настройки и БД отдельно (см. [Несколько копий](#несколько-копий-приложения)).

---

## Меню трея

![Меню трея](images/tray-menu.png)

| Пункт | Что делает |
|---|---|
| **Статус / Последний / Новых / Следующий** | Информационные строки (нельзя нажать). Показывают результат последнего цикла и время следующего. |
| **Быстрое сканирование** | Однократный «лёгкий» проход — проверка нескольких последних страниц на новые объявления. Не зависит от расписания. |
| **Полное сканирование** | Однократный полный обход каталога (~200 страниц) для детекта изменений цены, пробега и т.п. |
| **Запустить расписание** | Включить автоматический режим — циклы по заданному интервалу. |
| **Остановить расписание** | Приостановить циклы (но `Run now` продолжает работать). |
| **Отправить отчёт сейчас** | Сформировать письмо из накопленных карточек и отправить. Без сканирования. |
| **Отправить отчёт об ошибках** | Принудительно отправить накопленные ошибки (если есть). |
| **Сбросить отметки об отправке** | Забыть `email_sent_at` у всех карточек — следующая отправка включит ВСЁ из БД. С подтверждением. |
| **Удалить старые отчёты** | Подмести `reports/` от CSV-файлов старше N дней. |
| **Настройки…** | Открыть окно настроек. |
| **Открыть папку данных / отчётов** | Запустить Explorer в `%APPDATA%\major-scraper\<id>\`. |
| **Очистить базу** | Удалить все строки из БД. С подтверждением. |
| **Выход** | Завершить приложение. |

---

## Настройки

Окно **Настройки** содержит четыре вкладки. Все изменения применяются после нажатия **Сохранить**. Расписание подхватывает новые значения с следующего тика.

### Вкладка «Сканирование»

![Сканирование](images/settings-scan.png)

Расписание работает **в двух режимах**: лёгкий (часто, для поиска новых) и полный (редко, для отслеживания изменений).

**Адреса** — URL'ы каталога, которые надо обходить. По одному на строку. Можно с фильтрами в пути:
- `https://www.major-expert.ru/cars/all/` — весь каталог
- `https://www.major-expert.ru/cars/moscow/?priceTo=5000000` — только Москва, цена до 5 млн

**Быстрое сканирование (light):**
- *Интервал (мин)* — как часто запускается. По умолчанию 5.
- *Макс. страниц* — глубина обхода с конца. По умолчанию 3 = последние 3 страницы каталога. Используется reverse-обход + автоматическая ранняя остановка после 2 «чистых» страниц. На практике 3-5 страниц достаточно — новые объявления у дилера попадают в конец сортировки «по популярности».

**Полное сканирование (full):**
- *Интервал (часов)* — как часто запускается. По умолчанию 12 = два раза в день.
- *Макс. страниц* — глубина. По умолчанию 250 (с запасом, в каталоге ~200 страниц).

> Полное сканирование устойчиво к простоям. Если приложение было выключено сутки, а интервал 12 часов — на старте автоматически запустится full, чтобы не пропустить изменения.

**Общее:**
- *Порядок (orderBy)* — `popular`, `newest`, `price_asc`, `price_desc`. Параметр API. По умолчанию `popular`.
- *Направление обхода* — `forward` (от 1-й страницы) или `reverse` (с последней). По умолчанию `reverse` — потому что в `popular` новые объявления внизу.
- *Уведомлять о* — `new` (только новые) или `new_or_updated` (плюс изменения цены/пробега). По умолчанию `new_or_updated`.

### Вкладка «Поля»

![Поля](images/settings-fields.png)

Список из 36 полей, которые попадают в CSV-вложение и в HTML-таблицу письма. **На БД это не влияет** — в базу всегда пишутся все поля. Здесь только что показывать в отчёте.

Кнопки **Все / Никакие / По умолчанию** — пресеты выбора.

Пример «коротких» полей по умолчанию: `id, url, brand, model, year, mileage_km, price_rub, city, first_seen_at, last_changed_at`.

### Вкладка «API»

![API](images/settings-api.png)

Технические параметры подключения к закрытому API сайта. Менять только если перестало работать.

| Поле | Значение по умолчанию | Зачем |
|---|---|---|
| API URL | `https://www.major-expert.ru/api2/public/cars/items-by-url/` | POST-эндпоинт со списком карточек |
| Bootstrap URL | `https://www.major-expert.ru/cars/all/` | GET, который выдаёт cookie `filter_session` (используется как `_mj_token`) |
| Регексп токена | `_mj_token["\'\s:=]+([A-F0-9]{32})` | Резервный путь — поиск токена прямо в HTML, если cookie не пришла |
| Запросов/сек | 0.7 | Throttle. Безопасный диапазон 0.3–1.5. |
| Таймаут (с) | 20 | Таймаут одного HTTP-запроса |

> При 429 (rate-limited) клиент сам уходит в long backoff: 60 → 120 → 240 → 480 секунд. Дополнительно поднимает throttle до 2 с/запрос.

### Вкладка «Почта»

![Почта](images/settings-email.png)

**SMTP-сервер** — параметры исходящей почты.

Готовые рецепты:

| Провайдер | Хост | Порт | Шифрование | Примечание |
|---|---|---|---|---|
| Mail.ru | `smtp.mail.ru` | 465 | ssl | Нужен **App Password** (не обычный пароль ящика!). Создаётся в [настройках безопасности](https://account.mail.ru/user/2-step-auth/passwords/). |
| Mail.ru (альт.) | `smtp.mail.ru` | 587 | starttls | То же |
| Gmail | `smtp.gmail.com` | 587 | starttls | App Password |
| Яндекс | `smtp.yandex.ru` | 465 | ssl | App Password |
| Свой сервер | твой хост | 587 | starttls | Обычный логин/пароль |

> При смене **Шифрования** порт автоматически подставляется (`starttls`→587, `ssl`→465, `none`→25). Можешь поменять руками.
> Если SMTP не требует логина (внутренний сервер, аутентификация по IP) — оставь *Пользователь* пустым, AUTH будет пропущен.

**Получатели:**
- *От* — адрес отправителя. Должен совпадать с доменом, разрешённым у SMTP-провайдера. Mail.ru разрешает свой `@mail.ru`, чужие — отбивает.
- *Кому* — куда слать отчёт.
- *Копия отчётов об ошибках* — адрес(а) для CC при отправке отчёта об ошибках. Можно через запятую. По умолчанию `info@borisovai.ru` для технической поддержки.

**Хранение CSV-отчётов:**
- *Удалять CSV сразу после успешной отправки* — экономит место. По умолчанию включено.
- *Авто-удаление старше N дней* — для тех CSV, которые не удалились (например, при ошибке отправки). По умолчанию 30. `0` = не удалять.

---

## Цвет иконки в трее

| Цвет | Значение |
|---|---|
| 🔵 синий | Idle — расписание работает, ожидание следующего цикла |
| 🟠 оранжевый | Идёт сканирование |
| 🟢 зелёный | Последний цикл нашёл новые карточки |
| 🔴 красный | **Ошибки не доставлены по почте** или цикл упал. Подведи курсор — в подсказке `⚠ N error(s) couldn't be delivered…` |
| ⚪ серый | Расписание остановлено (paused) |

При наведении мышью отображается tooltip с деталями последнего цикла.

---

## Хранение данных

Все файлы лежат в `%APPDATA%\major-scraper\<install_id>\`:

```
%APPDATA%\major-scraper\<id>\
├── settings.json        ← настройки (создаётся при первом запуске)
├── cars.sqlite          ← БД с карточками + история изменений + отметки об отправке
├── scraper.log          ← общий лог приложения
├── alerts.log           ← журнал недоставленных уведомлений
└── reports\             ← CSV-вложения для писем
```

`<install_id>` — короткий sha1-хеш пути установки (12 hex). Открывается через меню **Открыть папку данных**.

---

## Несколько копий приложения

Один exe нельзя запустить дважды из одной папки — повторный запуск показывает диалог с предложением скопировать приложение в другую папку.

![Уже запущен](images/already-running.png)

Зачем это нужно: запустить **две независимые копии** с разными настройками (например, мониторить два разных сайта или два URL с разными почтовыми адресами).

**Процедура:**
1. Запустить уже работающий exe второй раз — появится диалог.
2. Нажать **Скопировать в другую папку…** — выбрать родительский каталог.
3. Дистрибутив скопируется как `MajorScraper-2`, `MajorScraper-3`, …
4. Запустить `MajorScraper.exe` из новой папки. У копии будет **свой `<install_id>`** → своя БД → свои настройки.

---

## Отчёты об ошибках

Если приложение поймало ошибку (сетевая, парсинг JSON, таймаут SMTP при отправке регулярного отчёта и т.п.), она копится в буфере. По окончании каждого цикла (или раз в `light_interval_minutes`) приложение пытается отправить **отчёт об ошибках** письмом на:

- **Кому** — адрес из настроек («Кому»)
- **CC** — адрес(а) из «Копия отчётов об ошибках»

Письмо содержит таблицу с timestamps, levels, источниками и stack trace'ами.

Если SMTP падает — отчёт **не теряется**, остаётся в буфере (cap=100, старые выпадают), retry на следующем тике. Иконка трея становится красной до тех пор, пока ошибки не уйдут.

Доп. журнал недоставленных алертов — в `alerts.log` рядом с `settings.json`.

---

## Решение проблем

### 429 Too Many Requests

Сервер `major-expert.ru` режет частоту запросов с твоего IP. Клиент сам уходит в long backoff (до 8 минут). Если повторяется регулярно — уменьши **Запросов/сек** (Настройки → API) до 0.3–0.5 и **Интервал полного сканирования** до 24+ часов.

### 550 «domain not verified» (Resend)

Resend.com требует верификацию домена отправителя. `borisovai.ru` не верифицирован у Resend → каждое письмо отбивается.
Решения:
- Перейти на свой SMTP (`mail.borisovai.ru`) — он принимает свой же домен.
- Либо в Resend Dashboard → Domains → добавить `borisovai.ru`, прописать SPF/DKIM в DNS.
- Либо временно `mail_from = onboarding@resend.dev` (единственный верифицированный по умолчанию).

### Письмо не уходит, иконка красная

1. Открой Настройки → Почта, проверь параметры. Mail.ru/Gmail/Яндекс **требуют App Password**, не основной пароль.
2. Открой `scraper.log` — там есть `WARNING ... error report send FAILED: ...` с точной причиной.
3. Принудительно: **Отправить отчёт сейчас** в меню трея.

### Settings dialog не открывается / окно невидимое

Бывало в редких случаях с DPI scaling. Закрой приложение через Quit, удали `settings.json` (бэкап оставит), запусти заново. Если повторяется — лог поможет.

### `_mj_token not found`

Сайт major-expert.ru сменил структуру или твой IP заблокирован. Проверь в браузере:
1. Открывается ли `https://www.major-expert.ru/cars/all/`?
2. Если нет → IP в бане, подожди 10–15 минут.
3. Если открывается, но скрапер не работает — возможно, сайт обновили. Покажи лог разработчику.

### Toast-уведомления не появляются

Windows может фильтровать toast'ы (Focus Assist, отключенные уведомления). Это **не критично** — сигнал о провале есть в:
- Красная иконка трея + tooltip
- `alerts.log`
- `scraper.log`

Включить toast'ы: Параметры Windows → Система → Уведомления → разрешить для приложений.

---

## Дополнительно

- **Логи**: `%APPDATA%\major-scraper\<id>\scraper.log` — основной журнал.
- **Сборка из исходников**: см. `README.md` рядом с этим файлом.
- **Связь с разработчиком**: `info@borisovai.ru`.
