Files
docs/content/iptvc/dev/arch.md
T
2026-07-16 12:07:22 +08:00

11 KiB
Raw Blame History

tags
tags
iptvc
разработка
архитектура

Архитектура 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

Структуры: ConfigAppConfig, 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-запрос с Range header.
  • 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-блоком.

Кеширование

Два уровня кеша:

  1. Redis/KeyDB (опционально) — постоянный кеш результатов проверки. TTL из cache.ttl.
  2. In-memory (memCache) — только при serve --check. Обновляется в реальном времени через callback. Не требует Redis.

In-memory кеш приоритетнее Redis при отображении в веб-интерфейсе.