/* * Copyright (c) 2025-2026, Антон Аксенов * This file is part of iptvc project * MIT License: https://git.axenov.dev/IPTV/iptvc/src/branch/master/LICENSE */ package cmd import ( "axenov/iptv-checker/app" "axenov/iptv-checker/app/config" "github.com/spf13/cobra" ) // addCommonCheckFlags добавляет общие флаги, используемые как командой check, // так и serve. Флаги используют zero-value defaults; переопределение config.yml // происходит через cmd.Flags().Changed() в applyCacheOverrides() и applyCheckOverrides(). func addCommonCheckFlags(cmd *cobra.Command, repeatDefault uint) { // paths cmd.Flags().StringVarP(&app.Args.IniPath, "ini", "i", "", "path to a local ini-file (overrides config.yml)") cmd.Flags().StringVarP(&app.Args.TagsPath, "tags", "t", "", "path to a local tagfile (overrides config.yml)") // iteration cmd.Flags().UintVarP(&app.Args.RandomCount, "random", "r", 0, "take this count of random playlists to check from ini-file") cmd.Flags().UintVarP(&app.Args.RepeatCount, "repeat", "", repeatDefault, "repeat same check X times (0 = infinite)") // check.playlists cmd.Flags().IntVar(&app.Args.PlTimeout, "playlists-timeout", 0, "playlist request timeout in seconds (overrides config.yml)") cmd.Flags().IntVar(&app.Args.PlAllCooldown, "playlists-all-cooldown", 0, "cooldown after all playlists in seconds (overrides config.yml)") cmd.Flags().IntVar(&app.Args.PlOneCooldown, "playlists-one-cooldown", 0, "cooldown after each playlist in seconds (overrides config.yml)") cmd.Flags().IntVar(&app.Args.PlMaxRoutines, "playlists-max-routines", 0, "max concurrent playlist checks (overrides config.yml)") cmd.Flags().IntVar(&app.Args.PlPerRoutine, "playlists-per-routine", 0, "playlists per routine (overrides config.yml)") cmd.Flags().StringSliceVar(&app.Args.PlUserAgent, "playlists-user-agent", nil, "user-agent for playlist requests (overrides config.yml)") // check.channels cmd.Flags().IntVar(&app.Args.ChTimeout, "channels-timeout", 0, "channel request timeout in seconds (overrides config.yml)") cmd.Flags().IntVar(&app.Args.ChByteRange, "channels-byte-range", 0, "bytes to fetch from server per channel (overrides config.yml)") cmd.Flags().IntVar(&app.Args.ChCooldown, "channels-cooldown", 0, "cooldown after each channel in seconds (overrides config.yml)") cmd.Flags().IntVar(&app.Args.ChMaxRoutines, "channels-max-routines", 0, "max concurrent channel checks (overrides config.yml)") cmd.Flags().IntVar(&app.Args.ChPerRoutine, "channels-per-routine", 0, "channels per routine (overrides config.yml)") cmd.Flags().StringSliceVar(&app.Args.ChUserAgent, "channels-user-agent", nil, "user-agent for channel requests (overrides config.yml)") // cache cmd.Flags().BoolVar(&app.Args.CacheEnabled, "cache-enabled", false, "enable cache (overrides config.yml)") cmd.Flags().StringVar(&app.Args.CacheHost, "cache-host", "", "cache host (overrides config.yml)") cmd.Flags().UintVar(&app.Args.CachePort, "cache-port", 0, "cache port (overrides config.yml)") cmd.Flags().StringVar(&app.Args.CacheUsername, "cache-username", "", "cache username (overrides config.yml)") cmd.Flags().StringVar(&app.Args.CachePassword, "cache-password", "", "cache password (overrides config.yml)") cmd.Flags().UintVar(&app.Args.CacheDb, "cache-db", 0, "cache database number (overrides config.yml)") cmd.Flags().UintVar(&app.Args.CacheTtl, "cache-ttl", 0, "cache TTL in seconds (overrides config.yml)") } // addCheckOnlyFlags добавляет флаги, доступные только в команде check. func addCheckOnlyFlags(cmd *cobra.Command) { cmd.Flags().BoolVarP(&app.Args.NeedJson, "json", "j", false, "print results in JSON format in the end") cmd.Flags().BoolVarP(&app.Args.NeedQuiet, "quiet", "q", false, "suppress logs (does not affect on -j)") cmd.Flags().StringSliceVarP(&app.Args.Files, "file", "f", []string{}, "path to a local playlist file (m3u/m3u8)") cmd.Flags().StringSliceVarP(&app.Args.Urls, "url", "u", []string{}, "URL to a remote playlist (http/https)") cmd.Flags().StringSliceVarP(&app.Args.Codes, "code", "c", []string{}, "code of playlist from ini-file") } // applyAppOverrides применяет CLI-флаги для app.* поверх конфигурации. // Использует Changed() — переопределение срабатывает только при явной передаче флага. func applyAppOverrides(cmd *cobra.Command) { if cmd.Flags().Changed("debug") { app.Config.App.Debug = app.Args.Debug } if cmd.Flags().Changed("log-level") { app.Config.App.LogLevel = app.Args.LogLevel } if cmd.Flags().Changed("ini") { app.Config.App.Playlists = app.Args.IniPath } if cmd.Flags().Changed("tags") { app.Config.App.Tags = app.Args.TagsPath } } // applyCacheOverrides применяет CLI-флаги для cache.* поверх конфигурации. // Использует Changed() — переопределение срабатывает только при явной передаче флага. // Вызывается между app.Init() и app.InitCache(). func applyCacheOverrides(cmd *cobra.Command) { c := &app.Config.Cache if cmd.Flags().Changed("cache-enabled") { c.Enabled = app.Args.CacheEnabled } if cmd.Flags().Changed("cache-host") { c.Host = app.Args.CacheHost } if cmd.Flags().Changed("cache-port") { c.Port = app.Args.CachePort } if cmd.Flags().Changed("cache-username") { c.Username = app.Args.CacheUsername } if cmd.Flags().Changed("cache-password") { c.Password = app.Args.CachePassword } if cmd.Flags().Changed("cache-db") { c.Db = app.Args.CacheDb } if cmd.Flags().Changed("cache-ttl") { c.Ttl = app.Args.CacheTtl } } // applyCheckOverrides применяет CLI-флаги для check.* поверх конфигурации. // Значения времени передаются в секундах и переводятся в миллисекунды. // Вызывается в обработчиках check и serve после app.Init(). func applyCheckOverrides(cmd *cobra.Command) { pp := &app.Config.Check.Playlists if cmd.Flags().Changed("playlists-timeout") { pp.Timeout = config.DurationSeconds(app.Args.PlTimeout * 1000) } if cmd.Flags().Changed("playlists-all-cooldown") { pp.AllCooldown.Min = app.Args.PlAllCooldown * 1000 pp.AllCooldown.Max = app.Args.PlAllCooldown * 1000 } if cmd.Flags().Changed("playlists-one-cooldown") { pp.OneCooldown.Min = app.Args.PlOneCooldown * 1000 pp.OneCooldown.Max = app.Args.PlOneCooldown * 1000 } if cmd.Flags().Changed("playlists-max-routines") { pp.MaxRoutines = app.Args.PlMaxRoutines } if cmd.Flags().Changed("playlists-per-routine") { pp.PerRoutine = app.Args.PlPerRoutine } if cmd.Flags().Changed("playlists-user-agent") { pp.UserAgent = app.Args.PlUserAgent } cc := &app.Config.Check.Channels if cmd.Flags().Changed("channels-timeout") { cc.Timeout = config.DurationSeconds(app.Args.ChTimeout * 1000) } if cmd.Flags().Changed("channels-byte-range") { cc.ByteRange = app.Args.ChByteRange } if cmd.Flags().Changed("channels-cooldown") { cc.Cooldown.Min = app.Args.ChCooldown * 1000 cc.Cooldown.Max = app.Args.ChCooldown * 1000 } if cmd.Flags().Changed("channels-max-routines") { cc.MaxRoutines = app.Args.ChMaxRoutines } if cmd.Flags().Changed("channels-per-routine") { cc.PerRoutine = app.Args.ChPerRoutine } if cmd.Flags().Changed("channels-user-agent") { cc.UserAgent = app.Args.ChUserAgent } }