реструктуризация файлов проекта
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
2026-08-30 10:08:43 +03:00
parent adc49c285c
commit 251fa0be11
21 changed files with 619 additions and 333 deletions
+153
View File
@@ -0,0 +1,153 @@
# Архитектура проекта
Версия: см. [`VERSION`](../VERSION). История изменений: [`docs/CHANGELOG.md`](CHANGELOG.md).
## Назначение
Система загружает посты и события из внешних источников, хранит их в MariaDB, публикует анонсы в Telegram-канал и даёт веб-интерфейс для редактирования и управления подписками через responder-бота.
Поддерживаются два режима работы (`WORKMODE` в `.env`):
| Режим | Источники данных | Публикация |
|-------|------------------|------------|
| **ZILANT** | VK (`vk_load.py`), JSON Zilant (`zk_load.py`) | `tg_publish.py`, `evtg_publish.py` |
| **VOLK** | VOLK API (`volk_load.py`) | `volk_cat_publish.py` |
Подробнее о VOLK: [`docs/volk-mode.md`](volk-mode.md).
## Компоненты runtime
```
┌─────────────────┐ rsync ┌──────────────────┐
│ Woodpecker CI │ ─────────────► │ /opt/testbot-git │
└─────────────────┘ └────────┬─────────┘
┌──────────────────────────────────┼──────────────────────────┐
▼ ▼ ▼
runner.timer testbot-git.service testedit-git.service
→ runner.sh gunicorn :5005 gunicorn :5006
vk_load, zk_load, wsgi_bot → tg_mainbot wsgi_edit → db_edit
db_update_shortname,
tg_publish, evtg_publish
```
### Responder-бот (подписки)
- **`tg_mainbot.py`** — Flask + webhook, обработка `/start`, callback-кнопок подписки.
- **`wsgi_bot.py`** — точка входа gunicorn; однократная регистрация webhook с file lock.
- **`season_links.py`** — сезонные payload (`zk2026_post_*`, `subscribe_zk2026_*` и т.д.).
- Старые ссылки без префикса сезона → сообщение «сезон завершён» + кнопка в канал.
### Poster (публикация в канал)
- **`tg_publish.py`** — посты VK → Telegram.
- **`evtg_publish.py`** — события → Telegram.
- **`volk_cat_publish.py`** — категории VOLK → Telegram (режим VOLK).
- Все исходящие вызовы Bot API — через **`telegram_relay.py`** (`RELAY_URL`).
### Веб-интерфейс
- **`db_edit.py`** — CRUD постов/событий, кнопки рескана, публикации, «Назвать» (AI shortname).
- **`db_update_shortname.py`** — генерация коротких названий через RouterAI.
- **`test_tg_poster.py`** — тестовый пост в канал (кнопка «Тест» в UI).
- Шаблоны: `templates/`.
### База данных
- **`ensure_db.py`** — создание/миграция схемы (вызывается из loader-скриптов).
- **`backupdb.sh`** — дамп БД при deploy (`post-deploy.sh`).
## Пайплайн runner.sh (ZILANT)
Порядок выполнения (systemd timer `runner.timer`):
1. `vk_load.py` — загрузка постов из VK
2. `zk_load.py` — загрузка событий из JSON
3. `db_update_shortname.py` — AI shortname для новых записей
4. `tg_publish.py` — публикация постов
5. `evtg_publish.py` — публикация событий
> **`tools/legacy/evt_prefetch.py`** раньше стоял перед `evtg_publish.py`; с 1.0.0 снят с пайплайна.
## Deploy
- **`.woodpecker.yml`** — rsync на сервер, затем `services/post-deploy.sh`.
- **`post-deploy.sh`** — venv, pip, backup БД, обновление systemd units, restart сервисов.
## Конфигурация (.env)
| Переменная | Назначение |
|------------|------------|
| `WORKMODE` | `ZILANT` или `VOLK` |
| `SEASON` | Префикс сезона для deep link (`zk2026`) |
| `RELAY_URL` | Internal relay для Bot API |
| `WEBHOOK_URL`, `WEBHOOK_SECRET` | Доставка апдейтов боту |
| `MDB_*`, `MDBASE` | MariaDB |
| `POSTER_BOT_TOKEN`, `RESPONDER_BOT_TOKEN` | Токены ботов |
## Карта файлов
### Ядро (runtime)
| Файл | Роль |
|------|------|
| `tg_mainbot.py` | Responder-бот, webhook |
| `wsgi_bot.py` | Gunicorn entry (бот) |
| `db_edit.py` | Веб-UI |
| `wsgi_edit.py` | Gunicorn entry (UI) |
| `tg_publish.py` | Публикация постов |
| `evtg_publish.py` | Публикация событий |
| `vk_load.py` | Загрузка VK |
| `zk_load.py` | Загрузка Zilant JSON |
| `volk_load.py` | Загрузка VOLK (режим VOLK) |
| `volk_cat_publish.py` | Публикация VOLK (режим VOLK) |
| `db_update_shortname.py` | AI shortname |
| `formatter.py` | Форматирование текста постов/событий |
| `ensure_db.py` | Схема БД |
| `telegram_relay.py` | Relay для Bot API |
| `season_links.py` | Сезонные ссылки и callback |
| `test_tg_poster.py` | Тестовая публикация (UI) |
| `runner.sh` | Пайплайн по расписанию |
| `backupdb.sh` | Бэкап БД |
| `gunicorn_bot.conf.py` | Stub-конфиг gunicorn (бот) |
### Инфраструктура
| Путь | Роль |
|------|------|
| `services/testbot-git.service` | systemd: бот :5005 |
| `services/testedit-git.service` | systemd: UI :5006 |
| `services/runner.service`, `runner.timer` | systemd: hourly runner |
| `services/post-deploy.sh` | Post-deploy |
| `.woodpecker.yml` | CI deploy |
### Вспомогательные (`tools/`)
| Путь | Роль |
|------|------|
| `tools/ops/genkey.py` | Генерация секретов |
| `tools/ops/register_tg_webhook.py` | Ручная регистрация webhook |
| `tools/ops/copy_databases.sh` | Клонирование MariaDB |
| `tools/dev/send_telegram_example.py` | CLI-пример `/send_message` |
| `tools/dev/volk_telegram_testing.py` | Отладка публикации в Telegram |
| `tools/dev/volk_category_testing.py` | Отладка загрузки категории VOLK |
| `tools/legacy/evt_prefetch.py` | Legacy: prefetch событий |
См. [`tools/README.md`](../tools/README.md).
### Документация
| Файл | Содержание |
|------|------------|
| `README.md` | Быстрый старт |
| `docs/ARCHITECTURE.md` | Этот файл |
| `docs/volk-mode.md` | Режим VOLK |
| `docs/telegram-messaging.md` | API `/send_message` |
| `docs/runner-setup.md` | Настройка runner timer |
| `docs/CHANGELOG.md` | История версий |
## Версионирование
- Версия в корне: **`VERSION`** (SemVer: `MAJOR.MINOR.PATCH`).
- При каждом значимом изменении обновлять `VERSION` и запись в `docs/CHANGELOG.md`.
- Правило для агентов: `.cursor/rules/version-and-docs.mdc`.
+37
View File
@@ -0,0 +1,37 @@
# Changelog
Формат основан на [Keep a Changelog](https://keepachangelog.com/ru/1.1.0/).
Версия проекта — в файле [`VERSION`](../VERSION) (SemVer).
## [1.0.1] - 2026-08-30
### Changed
- Утилиты перенесены в `tools/`:
- `tools/ops/``register_tg_webhook.py`, `copy_databases.sh` (рядом с `genkey.py`)
- `tools/dev/``send_telegram_example.py`, `volk_telegram_testing.py`, `volk_category_testing.py`
- Скрипты в `tools/` загружают `.env` из корня проекта и добавляют корень в `sys.path` при импорте модулей ядра.
### Documentation
- Обновлены `tools/README.md`, `docs/ARCHITECTURE.md`, `docs/volk-mode.md`, `docs/telegram-messaging.md`, `README.md`.
## [1.0.0] - 2026-08-30
### Added
- Файл версии `VERSION` (SemVer).
- Документация: `README.md`, `docs/ARCHITECTURE.md`, `docs/volk-mode.md`.
- Каталог `tools/` с README; `tools/ops/genkey.py`, `tools/legacy/evt_prefetch.py`.
- Сезонные deep link и callback с префиксом `SEASON` (`season_links.py`, по умолчанию `zk2026`).
- Интеграция Telegram Bot API через internal relay (`telegram_relay.py`, `RELAY_URL`).
### Changed
- `evt_prefetch.py` перенесён в `tools/legacy/` — не входит в `runner.sh`.
- `genkey.py` перенесён в `tools/ops/`.
- Документация по runner и отправке сообщений — в `docs/`.
### Documentation
- Правило Cursor `.cursor/rules/version-and-docs.mdc` — поддержка версии и changelog при изменениях.
+75
View File
@@ -0,0 +1,75 @@
# Настройка автоматического запуска runner.sh
См. также [`docs/ARCHITECTURE.md`](ARCHITECTURE.md) — состав пайплайна.
Есть два способа настроить запуск `runner.sh` каждый час:
## Вариант 1: Systemd Timer (рекомендуется)
В проекте уже используются systemd-сервисы.
### Установка
1. Скопируйте файлы в systemd:
```bash
sudo cp services/runner.service /etc/systemd/system/
sudo cp services/runner.timer /etc/systemd/system/
```
2. Или используйте скрипт установки:
```bash
chmod +x services/install_runner_timer.sh
sudo bash services/install_runner_timer.sh
```
3. Вручную:
```bash
sudo systemctl daemon-reload
sudo systemctl enable runner.timer
sudo systemctl start runner.timer
```
### Управление
- Статус: `sudo systemctl status runner.timer`
- Остановить: `sudo systemctl stop runner.timer`
- Запустить: `sudo systemctl start runner.timer`
- Отключить: `sudo systemctl disable runner.timer`
- Логи: `sudo journalctl -u runner.service -f`
- Список timers: `sudo systemctl list-timers`
### Расписание
Файл `/etc/systemd/system/runner.timer`:
- `OnCalendar=hourly` — каждый час
- `OnCalendar=*-*-* *:00:00` — в начале каждого часа
- `OnCalendar=*-*-* 0,6,12,18:00:00` — в 0, 6, 12, 18 часов
- `OnCalendar=Mon..Fri 09:00:00` — будни в 9:00
После изменения: `sudo systemctl daemon-reload`
---
## Вариант 2: Cron
```bash
sudo crontab -e
```
```bash
0 * * * * /bin/bash /opt/testbot-git/runner.sh >> /opt/testbot-git/runner_cron.log 2>&1
```
Другие варианты: `30 * * * *`, `*/30 * * * *`, `0 9-17 * * *`.
---
## Состав runner.sh (ZILANT)
`vk_load.py``zk_load.py``db_update_shortname.py``tg_publish.py``evtg_publish.py`
Legacy `tools/legacy/evt_prefetch.py` в пайплайн не входит (с 1.0.0).
+94
View File
@@ -0,0 +1,94 @@
# Отправка сообщений через Telegram бота
## Описание
В проект добавлена возможность отправки сообщений пользователям Telegram через бота по их ID. Функциональность включает:
1. **API endpoint** для отправки сообщений из других скриптов
2. **Интерфейс в веб-приложении** для отправки сообщений через браузер
3. **Обработку ошибок** и логирование всех операций
## Архитектура системы
Система состоит из двух основных компонентов:
- **Веб-интерфейс** (`db_edit.py`) - работает на порту **5006** (WEBCTRL_PORT)
- **Telegram бот** (`tg_mainbot.py`) - работает на порту **5005** (WEBHOOK_PORT)
API endpoint `/send_message` находится в Telegram боте, поэтому все запросы должны отправляться на порт **5005**.
### Конфигурация портов
Порты и URL настраиваются в файле `.env`:
- `RELAY_URL` - базовый URL **internal_relay** (все исходящие вызовы Bot API идут только через него)
- `WEBHOOK_PORT` - порт для Telegram бота (по умолчанию 5005)
- `WEBHOOK_URL` - URL доставки апдейтов от internal_relay к боту
- `WEBCTRL_PORT` - порт для веб-интерфейса (по умолчанию 5006)
## Использование через веб-интерфейс
В заголовке страницы добавлены поля **ID пользователя**, **Сообщение** и кнопка **Отправить**.
## Использование через API
### Endpoint
```
POST /send_message
POST {WEBHOOK_PATH}/send_message
```
### Заголовки
```
Content-Type: application/json
X-API-Secret-Token: <WEBHOOK_SECRET>
```
### Тело запроса
```json
{
"user_id": 123456789,
"message": "Текст сообщения"
}
```
### Пример (Python)
```python
import requests
def send_telegram_message(user_id, message):
url = "http://192.168.0.109:5005/testbot/send_message"
headers = {
"Content-Type": "application/json",
"X-API-Secret-Token": "ваш_секретный_токен",
}
response = requests.post(url, json={"user_id": user_id, "message": message}, headers=headers)
return response.json()
```
### Пример (curl)
```bash
curl -X POST http://localhost:5005/testbot/send_message \
-H "Content-Type: application/json" \
-H "X-API-Secret-Token: ваш_секретный_токен" \
-d '{"user_id": 123456789, "message": "Привет!"}'
```
Опционально: CLI-скрипт `tools/dev/send_telegram_example.py`.
## Коды ошибок API
- `INVALID_TOKEN`, `NO_DATA`, `NO_USER_ID`, `NO_MESSAGE`, `INVALID_USER_ID`
- `TELEGRAM_ERROR`, `INTERNAL_ERROR`
## Требования
- Бот запущен (webhook через `wsgi_bot.py`)
- Пользователь начал диалог с ботом (`/start`)
См. также [`ARCHITECTURE.md`](ARCHITECTURE.md).
+53
View File
@@ -0,0 +1,53 @@
# Режим VOLK
Режим включается в `.env`:
```env
WORKMODE = "VOLK"
```
Проект поддерживает оба режима — **ZILANT** и **VOLK**; переключение только через `WORKMODE`, без смены кодовой базы.
## Отличия от ZILANT
| Аспект | ZILANT | VOLK |
|--------|--------|------|
| Загрузка данных | `vk_load.py`, `zk_load.py` | `volk_load.py` |
| Публикация | `tg_publish.py`, `evtg_publish.py` | `volk_cat_publish.py` |
| Runner | Полный пайплайн ZILANT | Отдельные кнопки рескана в UI |
| UI | Посты + события VK/Zilant | Категории (площадки) + события VOLK |
## Модули VOLK
### `volk_load.py`
- Загружает список категорий и событий с VOLK API.
- Переменные: `VOLK_CATEGORY_LIST`, `VOLK_CATEGORY_DESC_PREFIX`, `VOLK_EVENT_LIST_PREFIX`, `VOLK_API_VERSION`.
- Вызывается из `db_edit.py` (API `/api/run_volk_rescan`, кнопка «Рескан ВОЛК»).
### `volk_cat_publish.py`
- Публикует категории (площадки) в Telegram-канал.
- Функции `tg_post_category_by_id`, `tg_post_all_categories` — из веб-UI.
### Шаблоны
- `templates/edit_category.html` — редактирование площадки (только VOLK).
- Блоки `{% if g.workmode == 'VOLK' %}` в `templates/index.html`.
## Отладочные скрипты (не в production-пайплайне)
| Файл | Запуск |
|------|--------|
| `tools/dev/volk_category_testing.py` | `python tools/dev/volk_category_testing.py <category_id>` |
| `tools/dev/volk_telegram_testing.py` | `python tools/dev/volk_telegram_testing.py` |
См. [`tools/README.md`](../tools/README.md).
## Переключение режима на сервере
1. Изменить `WORKMODE` в `/opt/testbot-git/.env`.
2. Перезапустить UI: `sudo systemctl restart testedit-git.service`.
3. Responder-бот (`testbot-git`) от режима не зависит; сезонные ссылки общие (`SEASON`).
При смене режима проверьте переменные VOLK/ZILANT в `.env` (префиксы URL, API, `LOG_FILE`).