188 lines
9.7 KiB
Markdown
188 lines
9.7 KiB
Markdown
# Контекст проекта: 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`) |
|