package internal import ( "fmt" netHttp "net/http" "os" "strings" "time" // _ "net/http/pprof" // Register pprof "github.com/debridmediamanager/zurg/internal/config" "github.com/debridmediamanager/zurg/internal/handlers" "github.com/debridmediamanager/zurg/internal/torrent" "github.com/debridmediamanager/zurg/internal/universal" "github.com/debridmediamanager/zurg/internal/version" "github.com/debridmediamanager/zurg/pkg/http" "github.com/debridmediamanager/zurg/pkg/logutil" "github.com/debridmediamanager/zurg/pkg/premium" "github.com/debridmediamanager/zurg/pkg/realdebrid" "github.com/debridmediamanager/zurg/pkg/utils" "github.com/go-chi/chi/v5" "github.com/panjf2000/ants/v2" "go.uber.org/zap/zapcore" ) func MainApp(configPath string) { utils.EnsureDirExists("logs") // log files utils.EnsureDirExists("data") // cache files (info, bins, etc.) utils.EnsureDirExists("data/info") utils.EnsureDirExists("dump") // "zurgtorrent" files dateStr := time.Now().Format(time.DateOnly) timeStr := strings.ReplaceAll(time.Now().Format(time.TimeOnly), ":", "-") logPath := fmt.Sprintf("logs/zurg-%s-%s.log", dateStr, timeStr) log := logutil.NewLogger(logPath) zurglog := log.Named("zurg") // logger for this main function zurglog.Debugf("PID: %d", os.Getpid()) zurglog.Infof("Version: %s", version.GetVersion()) zurglog.Infof("GitCommit: %s", version.GetGitCommit()) zurglog.Infof("BuiltAt: %s", version.GetBuiltAt()) if log.Level() == zapcore.DebugLevel { zurglog.Infof("Debug logging is enabled; if you are not debugging please set LOG_LEVEL=info in your system environment") } config, configErr := config.LoadZurgConfig(configPath, log.Named("config")) if configErr != nil { zurglog.Errorf("Config failed to load: %v", configErr) os.Exit(1) } apiClient := http.NewHTTPClient( config.GetToken(), config.GetRetriesUntilFailed(), // default retries = 2 config.GetApiTimeoutSecs(), // default api timeout = 60 false, // ipv6 support is not needed for api client config, log.Named("api_client"), ) unrestrictClient := http.NewHTTPClient( config.GetToken(), config.GetRetriesUntilFailed(), // default retries = 2 config.GetDownloadTimeoutSecs(), // default download timeout = 10 false, // this is also api client, so no ipv6 support config, log.Named("unrestrict_client"), ) downloadClient := http.NewHTTPClient( "", // no token required for download client config.GetRetriesUntilFailed(), // config.GetDownloadTimeoutSecs(), // true, // download client supports ipv6 config, log.Named("download_client"), ) workerPool, err := ants.NewPool(config.GetNumOfWorkers()) if err != nil { zurglog.Errorf("Failed to create worker pool: %v", err) os.Exit(1) } defer workerPool.Release() api := realdebrid.NewRealDebrid( apiClient, unrestrictClient, downloadClient, workerPool, config, log.Named("realdebrid"), ) premium.MonitorPremiumStatus( workerPool, api, zurglog, ) torrentMgr := torrent.NewTorrentManager( config, api, workerPool, log.Named("manager"), log.Named("repair"), ) downloader := universal.NewDownloader(downloadClient) router := chi.NewRouter() handlers.AttachHandlers( router, downloader, torrentMgr, config, api, workerPool, log.Named("router"), ) //// pprof workerPool.Submit(func() { if err := netHttp.ListenAndServe(":6060", nil); err != nil && err != netHttp.ErrServerClosed { zurglog.Errorf("Failed to start pprof: %v", err) os.Exit(1) } }) addr := fmt.Sprintf("%s:%s", config.GetHost(), config.GetPort()) zurglog.Infof("Starting server on %s", addr) if err := netHttp.ListenAndServe(addr, router); err != nil && err != netHttp.ErrServerClosed { zurglog.Errorf("Failed to start server: %v", err) os.Exit(1) } }