wip2
This commit is contained in:
187
AGENTS.md
Normal file
187
AGENTS.md
Normal file
@@ -0,0 +1,187 @@
|
||||
# Контекст проекта: 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`) |
|
||||
Reference in New Issue
Block a user