Files
iptvc/AGENTS.md
2026-06-01 20:29:34 +08:00

188 lines
9.7 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.
# Контекст проекта: IPTV Checker (iptvc)
> **Важно:** Этот файл создан автоматически на основе анализа кодовой базы. Используй его как справочный контекст при внесении изменений.
---
## Обзор проекта
**IPTV Checker (iptvc)** — консольная утилита для проверки доступности IPTV-плейлистов и каналов в форматах `m3u` / `m3u8`.
- **Назначение:** Быстрая массовая проверка плейлистов из файлов, по URL или из INI-реестра с расчётом статистики (online/offline).
- **Экосистема:** Часть проекта [m3u.su](https://m3u.su).
- **Лицензия:** MIT (см. `LICENSE`).
- **Автор:** Антон Аксенов.
### Основные технологии
- **Язык:** Go 1.23.6+
- **CLI-фреймворк:** [spf13/cobra](https://github.com/spf13/cobra)
- **Кеширование:** [Redis / KeyDB](https://github.com/redis/go-redis) (опционально, через `go-redis/v9`)
- **Конфигурация окружения:** [godotenv](https://github.com/joho/godotenv) + переменные окружения
- **Парсинг INI:** [gopkg.in/ini.v1](https://gopkg.in/ini.v1)
### Архитектура
Приложение построено по классической для Go CLI схеме:
```
cmd/ — команды Cobra (root, check)
app/ — бизнес-логика и инфраструктура
app.go — инициализация конфигурации, логгера, кеша; глобальные аргументы
checker/ — ядро проверки: подготовка списков, HTTP-опрос каналов, семафоры
playlist/ — модели Playlist/Channel/Group, парсинг m3u/m3u8
inifile/ — чтение реестра плейлистов из INI
config/ — чтение конфигурации из env (.env)
cache/ — подключение к Redis/KeyDB
logger/ — настройка вывода логов
tagfile/ — работа с файлом тегов (channels.json)
utils/ — вспомогательные функции (MD5, Fetch, ExpandPath и др.)
main.go — точка входа: контекст с отменой по сигналу, делегация cmd.ExecuteContext
```
---
## Сборка и запуск
### Локальная разработка
```bash
# Быстрый запуск из исходников
go run .
# Сборка бинаря
go build -o iptvc .
# Показать справку
./iptvc help
# Проверить плейлист из файла
./iptvc check -f mypls.m3u
# Проверить плейлист по ссылке
./iptvc check -u http://m3u.su/XYZ
# Проверить плейлисты из INI-файла
./iptvc check -i playlists.ini
# Только JSON-результат, без логов
./iptvc check -f mypls.m3u -j -q
```
### Makefile
| Команда | Описание |
|---------|----------|
| `make help` | Справка по целям |
| `make fmt` | `go fmt ./...` |
| `make vet` | `go vet ./...` |
| `make tidy` | `go mod tidy && go mod verify` |
| `make lint` | `fmt` + `vet` + сборка в `/dev/null` |
| `make clean` | Удаление скомпилированных бинарей и `bin/` |
| `make linux` | Сборка для Linux (`GOARCH=amd64` по умолчанию) |
| `make win` | Сборка для Windows |
| `make darwin` | Сборка для macOS |
| `make release` | Полный релиз: все ОС × amd64 + arm64, упаковка в zip |
> **Примечание:** Переменная `GOARCH` переопределяется через окружение, например: `make linux GOARCH=arm64`.
### Docker
```bash
# Ручная сборка образа
docker build -t iptvc:latest .
# Скрипт сборки и публикации (с версионированием через git-тег)
./build-docker-image.sh [TAG]
```
Dockerfile использует многоступенчатую сборку:
1. `golang:1.25-alpine` — компиляция бинаря (`CGO_ENABLED=0`, `trimpath`, `ldflags`)
2. `alpine:3.22.2` — финальный минимальный образ с непривилегированным пользователем.
---
## Конфигурация
Приложение читает переменные окружения (файл `.env` опционален).
| Переменная | По умолчанию | Описание |
|------------|--------------|----------|
| `CACHE_ENABLED` | `false` | Включить подключение к кешу |
| `CACHE_HOST` | `localhost` | Хост Redis/KeyDB |
| `CACHE_PORT` | `6379` | Порт |
| `CACHE_USERNAME` | — | Пользователь |
| `CACHE_PASSWORD` | — | Пароль |
| `CACHE_DB` | `0` | Номер БД |
| `CACHE_TTL` | `1800` | TTL записей в секундах |
> Файл `.env.example` содержит пример заполнения.
---
## Ключевые файлы и пакеты
| Путь | Назначение |
|------|------------|
| `main.go` | Точка входа: `context.WithCancel`, обработка `SIGINT`/`SIGTERM`, вызов `cmd.ExecuteContext` |
| `cmd/root.go` | Корневая команда Cobra, глобальный флаг `--verbose` |
| `cmd/check.go` | Команда `check`: флаги (`-f`, `-u`, `-i`, `-c`, `-t`, `-r`, `-j`, `-q`, `--repeat`, `--every`), цикл повторений, вызов `checker` |
| `app/app.go` | Глобальные объекты `Args`, `Cache`, `Config`; `Init()` и `Shutdown()` |
| `app/checker/checker.go` | **Ядро:** подготовка списков, скачивание плейлистов, HTTP-опрос каналов с семафором, динамический расчёт `timeout`/`routines`, кеширование результатов |
| `app/playlist/playlist.go` | Структуры `Playlist`, `Channel`, `Group`; парсинг m3u/m3u8 (атрибуты `#EXTINF`, `#EXTGRP`, заголовок `#EXTM3U`) |
| `app/config/config.go` | Чтение конфигурации из env с дефолтами |
| `app/inifile/inifile.go` | Чтение реестра плейлистов в формате INI |
| `app/cache/cache.go` | Инициализация клиента Redis/KeyDB |
| `app/tagfile/tagfile.go` | Загрузка и поиск тегов для каналов |
| `app/utils/utils.go` | Утилиты: `Fetch`, `ExpandPath`, `Md5str`, `ArrayUnique` |
| `app/utils/utils_test.go` | Тесты утилит |
| `app/config/config_test.go` | Тесты конфигурации |
| `app/playlist/playlist_test.go` | Тесты парсера плейлистов |
| `docs/json.md` | Документация по структуре JSON-вывода |
| `build-docker-image.sh` | Скрипт сборки и пуша Docker-образа с версией из git |
| `Dockerfile` | Многоступенчатая сборка контейнера |
---
## Правила разработки
### Стиль кода
- Код оформлен в едином стиле с лидирующими комментариями-заголовками (автор, лицензия, ссылка на репозиторий).
- Используются экспортируемые имена с подробными комментариями на русском языке (доминирующий язык комментариев).
- Глобальные переменные приложения (`Args`, `Cache`, `Config`) расположены в `app/app.go`.
### Тестирование
- Модульные тесты присутствуют для пакетов `utils`, `config`, `playlist`.
- Для запуска: `go test ./...`.
### Линтинг
- В Makefile есть цель `lint`, объединяющая `go fmt`, `go vet` и проверочную сборку.
- Перед коммитом рекомендуется выполнять `make lint`.
### Работа с зависимостями
- Модули Go (`go.mod` / `go.sum`).
- Обновление/очистка: `make tidy`.
### Соглашения по логике
- **Динамические параметры проверки:** количество горутин и HTTP-таймаут рассчитываются в `calcParameters(count)` на основе числа каналов. Чем больше каналов — тем больше параллелизм, но таймаут сокращается.
- **Семафор:** количество одновременных проверок ограничено через буферизированный канал (`chSemaphores`).
- **User-Agent:** при проверке каналов используется фиксированный заголовок `Mozilla/5.0 WINK/1.31.1 (AndroidTV/9) HlsWinkPlayer`.
- **TLS:** проверка выполняется с `InsecureSkipVerify: true`.
- **Кеш:** результаты проверки плейлистов сериализуются в JSON и сохраняются в Redis с TTL.
---
## Коды возврата
| Код | Значение |
|-----|----------|
| `0` | Успех |
| `1` | Общая ошибка |
| `2` | Команда `check` запущена без параметров `-f`, `-u` и `-c` (и нет INI по умолчанию) |
| `130` | Прерывание по сигналу (`SIGINT` / `SIGTERM`) |