127 lines
3.2 KiB
Go
127 lines
3.2 KiB
Go
package config
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"net/url"
|
|
"os"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
// Config holds all application configuration
|
|
type Config struct {
|
|
BotToken string
|
|
Masters []string
|
|
RPCURL string
|
|
Username string
|
|
Password string
|
|
LogFile string
|
|
TransLogFile string
|
|
NoLive bool
|
|
Interval time.Duration
|
|
Duration int
|
|
}
|
|
|
|
// LoadConfig loads configuration from flags and environment variables
|
|
func LoadConfig() (*Config, error) {
|
|
cfg := &Config{
|
|
Interval: DefaultUpdateInterval,
|
|
Duration: DefaultUpdateDuration,
|
|
}
|
|
|
|
var masters masterSlice
|
|
|
|
flag.StringVar(&cfg.BotToken, "token", "", "Telegram bot token, Can be passed via environment variable 'TT_BOTT'")
|
|
flag.Var(&masters, "master", "Your telegram handler, So the bot will only respond to you. Can specify more than one")
|
|
flag.StringVar(&cfg.RPCURL, "url", DefaultRPCURL, "Transmission RPC URL")
|
|
flag.StringVar(&cfg.Username, "username", "", "Transmission username")
|
|
flag.StringVar(&cfg.Password, "password", "", "Transmission password")
|
|
flag.StringVar(&cfg.LogFile, "logfile", "", "Send logs to a file")
|
|
flag.StringVar(&cfg.TransLogFile, "transmission-logfile", "", "Open transmission logfile to monitor torrents completion")
|
|
flag.BoolVar(&cfg.NoLive, "no-live", false, "Don't edit and update info after sending")
|
|
|
|
flag.Usage = func() {
|
|
fmt.Fprint(os.Stderr, "Usage: transmission-telegram <-token=TOKEN> <-master=@tuser> [-master=@yuser2] [-url=http://] [-username=user] [-password=pass]\n\n")
|
|
flag.PrintDefaults()
|
|
}
|
|
|
|
flag.Parse()
|
|
|
|
// Check environment variable for bot token
|
|
if cfg.BotToken == "" {
|
|
if token := os.Getenv("TT_BOTT"); len(token) > 1 {
|
|
cfg.BotToken = token
|
|
}
|
|
}
|
|
|
|
// Check environment variable for Transmission auth
|
|
if cfg.Username == "" {
|
|
if values := strings.Split(os.Getenv("TR_AUTH"), ":"); len(values) > 1 {
|
|
cfg.Username, cfg.Password = values[0], values[1]
|
|
}
|
|
}
|
|
|
|
// Convert masters slice
|
|
cfg.Masters = []string(masters)
|
|
for i := range cfg.Masters {
|
|
cfg.Masters[i] = strings.ReplaceAll(cfg.Masters[i], "@", "")
|
|
cfg.Masters[i] = strings.ToLower(cfg.Masters[i])
|
|
}
|
|
|
|
// Validate configuration
|
|
if err := cfg.Validate(); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return cfg, nil
|
|
}
|
|
|
|
// Validate checks if configuration is valid
|
|
func (c *Config) Validate() error {
|
|
if c.BotToken == "" {
|
|
return fmt.Errorf("bot token is required (use -token flag or TT_BOTT environment variable)")
|
|
}
|
|
|
|
if len(c.Masters) < 1 {
|
|
return fmt.Errorf("at least one master is required (use -master flag)")
|
|
}
|
|
|
|
if c.RPCURL != "" {
|
|
if _, err := url.Parse(c.RPCURL); err != nil {
|
|
return fmt.Errorf("invalid RPC URL: %w", err)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// IsMaster checks if username is in masters list
|
|
func (c *Config) IsMaster(username string) bool {
|
|
username = strings.ToLower(username)
|
|
for _, master := range c.Masters {
|
|
if master == username {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// PrintUsage prints usage information
|
|
func PrintUsage() {
|
|
flag.Usage()
|
|
}
|
|
|
|
// masterSlice is a custom type for flag parsing
|
|
type masterSlice []string
|
|
|
|
func (masters *masterSlice) String() string {
|
|
return fmt.Sprintf("%s", *masters)
|
|
}
|
|
|
|
func (masters *masterSlice) Set(master string) error {
|
|
*masters = append(*masters, strings.ToLower(master))
|
|
return nil
|
|
}
|
|
|