11 KiB
tags
| tags | |||
|---|---|---|---|
|
Архитектура iptvc
Внутреннее устройство программы для разработчиков.
Стек технологий
- Go 1.22+ — язык программирования;
net/http— HTTP-сервер (Go 1.22 routing patterns);html/template— шаблоны HTML;//go:embed— встраивание шаблонов в бинарник;github.com/spf13/cobra— CLI-фреймворк;gopkg.in/yaml.v3— парсингconfig.yml;github.com/joho/godotenv— загрузка.env;github.com/redis/go-redis/v9— клиент KeyDB/Redis.
Структура проекта
iptvc/
├── main.go # точка входа
├── config.yml # конфигурация
├── .env # переменные окружения (опционально)
├── cmd/ # CLI-команды (Cobra)
│ ├── root.go # корневая команда, глобальные флаги
│ ├── check.go # команда check
│ ├── serve.go # команда serve
│ ├── flags.go # общие флаги check/serve
│ └── version.go # команда version
├── app/
│ ├── app.go # глобальные переменные: Args, Config, Cache
│ ├── config/
│ │ └── config.go # Config, Init(), validate(), IntRange, UserAgents
│ ├── checker/
│ │ └── checker.go # CheckPlaylists(), CheckChannels(), OnPlaylistChecked
│ ├── playlist/
│ │ └── playlist.go # Playlist, Channel, Parse(), Download()
│ ├── inifile/
│ │ └── inifile.go # чтение playlists.ini
│ ├── tagfile/
│ │ └── tagfile.go # чтение channels.json, назначение тегов
│ ├── cache/
│ │ └── cache.go # подключение к KeyDB/Redis
│ ├── logger/
│ │ └── logger.go # настройка логирования
│ ├── utils/
│ │ └── utils.go # Fetch(), ExpandPath(), ArrayUnique(), Md5str()
│ └── web/
│ ├── server.go # Server, Start(), StartBackgroundChecker()
│ ├── handlers.go # HTTP-обработчики
│ ├── templates.go # TemplateManager, //go:embed
│ └── views/ # HTML-шаблоны
│ ├── base.html
│ ├── list.html
│ ├── details.html
│ └── notfound.html
└── go.mod
Пакеты
app
Глобальный контейнер: Args (CLI-флаги), Config (конфигурация), Cache (Redis-клиент).
Init() загружает конфигурацию, инициализирует логгер и подключение к кешу.
app.config
Структуры: Config → AppConfig, ServerConfig, CheckConfig, CacheConfig.
Кастомные YAML-типы:
IntRange— скаляр или[min, max]. МетодValue()возвращает константу или случайное значение.UserAgents— строка или массив строк. МетодPick()возвращает случайный элемент.
Init(configPath) — загружает config.yml, применяет env, валидирует.
validate() — проверяет все значения, исправляет некорректные с логированием.
app.checker
Содержит логику проверки:
PrepareListsToCheck(files, urls, codes)— формирует список плейлистов из файлов, URL и кодов ini-файла.CheckPlaylists(lists)— параллельная проверка плейлистов (семфорper-routine), загрузка, парсинг, вызовCheckChannelsдля каждого.CheckChannels(pls)— параллельная проверка каналов (семфорper-routine), HTTP-запрос сRangeheader.OnPlaylistChecked— глобальный callback, вызывается после проверки каждого плейлиста. Используется веб-сервером для обновления in-memory кеша.cachePlaylist(pls)— сохранение результата в Redis (если включён).
Параметры проверки берутся из app.Config.Check.Playlists и app.Config.Check.Channels.
app.playlist
Playlist— плейлист: код, URL, контент, каналы, статус.Channel— канал: ID, название, URL, статус, теги.Download(userAgent, timeout)— загрузка по URL.ReadFromFs()— чтение из файла.Parse()— парсинг m3u/m3u8 контента.
app.web
Веб-сервер на net/http (Go 1.22 routing).
Server— структура: конфиг, кеш, шаблоны, in-memory кеш (memCacheсsync.RWMutex).Start()— запуск HTTP-сервера.StartBackgroundChecker(opts)— фоновая проверка в отдельной горутине.CheckOptions— параметры: Every, Repeat, Random, Files, Urls, Codes.
Маршруты (Go 1.22 patterns):
GET /api/playlists/{code} — JSON плейлиста
GET /api/version — версия
GET /api/health — здоровье сервиса
GET /api/stats — статистика
GET /{$} — главная (catch-all root)
GET /{path...} — все остальные маршруты (catch-all)
Catch-all /{path...} используется для избежания конфликтов паттернов в Go 1.22 mux.
In-memory кеш (memCache) обновляется через OnPlaylistChecked callback.
Это позволяет отображать результаты проверки в реальном времени без ожидания завершения цикла и без Redis.
ini-файл кешируется на 30 секунд, кеш сбрасывается при каждом обновлении memCache.
Жизненный цикл serve --check
main → app.Init() → web.NewServer() → go StartBackgroundChecker() → server.Start()
StartBackgroundChecker:
loop:
runCheckerOnce()
→ checker.PrepareListsToCheck()
→ checker.CheckPlaylists()
→ for each playlist (parallel, per-routine):
→ Download() / ReadFromFs()
→ Parse()
→ CheckChannels()
→ for each channel (parallel, per-routine):
→ HTTP GET with Range header
→ check status + content type
→ OnPlaylistChecked(pls) → memCache update
→ one-cooldown sleep
→ all-cooldown sleep
sleep(every)
if repeat > 0 && iteration >= repeat: stop
CLI-флаги
Общие (cmd/flags.go)
Используются командами check и serve --check:
| Флаг | Поле | Описание |
|---|---|---|
-i, --ini |
Args.IniPath |
Путь к playlists.ini |
-t, --tags |
Args.TagsPath |
Путь к channels.json |
-r, --random |
Args.RandomCount |
Случайные N плейлистов |
--repeat |
Args.RepeatCount |
Количество циклов (0 = бесконечно) |
--playlists-all-cooldown |
Args.PlAllCooldown |
Миллисекунд между циклами |
Только check (addCheckOnlyFlags)
| Флаг | Поле | Описание |
|---|---|---|
-j, --json |
Args.NeedJson |
Вывод в JSON |
-q, --quiet |
Args.NeedQuiet |
Подавить логи |
-f, --file |
Args.Files |
Локальные m3u файлы |
-u, --url |
Args.Urls |
URL плейлистов |
-c, --code |
Args.Codes |
Коды из ini-файла |
Только serve
| Флаг | Поле | Описание |
|---|---|---|
-p, --port |
Args.ServerPort |
Порт веб-сервера |
--host |
Args.ServerHost |
Хост привязки |
--check |
Args.NeedCheck |
Включить фоновую проверку |
Глобальные (cmd/root.go)
| Флаг | Поле | Описание |
|---|---|---|
--config |
Args.ConfigPath |
Путь к config.yml |
-v, --verbose |
Args.Verbose |
Подробный лог |
Конфигурация
Подробное описание параметров — в разделе config.yml.
Приоритет: Defaults < config.yml < Env < CLI-флаги.
CLI-флаги переопределяют конфигурацию только если переданы явно (cmd.Flags().Changed()).
Для этого в Cobra используются zero-value defaults (0, "", false), чтобы отличить «не передан» от «передан со значением по умолчанию».
Шаблоны
HTML-шаблоны встроены через //go:embed:
base.html— общий каркас (header, footer);list.html— список плейлистов с пагинацией;details.html— детали плейлиста и список каналов;notfound.html— страница 404.
SVG-логотипы каналов передаются через encodeURIComponent в data-URI для корректной работы с кавычками в HTML.
При отсутствии playlists.ini рендерится пустое состояние с alert-блоком.
Кеширование
Два уровня кеша:
- Redis/KeyDB (опционально) — постоянный кеш результатов проверки. TTL из
cache.ttl. - In-memory (
memCache) — только приserve --check. Обновляется в реальном времени через callback. Не требует Redis.
In-memory кеш приоритетнее Redis при отображении в веб-интерфейсе.