193 lines
5.3 KiB
Go
193 lines
5.3 KiB
Go
package internal
|
|
|
|
import (
|
|
"fmt"
|
|
netHttp "net/http"
|
|
"os"
|
|
"os/exec"
|
|
"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
|
|
|
|
log := logutil.NewLogger("logs/zurg.log")
|
|
|
|
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)
|
|
}
|
|
|
|
var proxyURL string
|
|
if config.GetProxy() != "" {
|
|
proxyURL = config.GetProxy()
|
|
zurglog.Infof("Using proxy: %s", proxyURL)
|
|
} else {
|
|
proxyURL = os.Getenv("PROXY")
|
|
}
|
|
|
|
repoClient4 := http.NewHTTPClient("", 0, 1, false, []string{}, proxyURL, nil, log.Named("network_test"))
|
|
repoClient6 := http.NewHTTPClient("", 0, 1, true, []string{}, proxyURL, nil, log.Named("network_test"))
|
|
repo := http.NewIPRepository(repoClient4, repoClient6, "", log.Named("network_test"))
|
|
|
|
var hosts []string
|
|
repo.NetworkTest(false, config.ShouldCacheNetworkTestResults())
|
|
hosts = repo.GetHosts(config.GetNumberOfHosts(), config.ShouldForceIPv6())
|
|
if len(hosts) == 0 {
|
|
zurglog.Errorf("No reachable hosts found. Trying again.")
|
|
for {
|
|
repo.NetworkTest(true, config.ShouldCacheNetworkTestResults())
|
|
hosts = repo.GetHosts(config.GetNumberOfHosts(), config.ShouldForceIPv6())
|
|
if len(hosts) == 0 {
|
|
zurglog.Errorf("No reachable hosts found. Trying again in 5 minutes.")
|
|
time.Sleep(5 * time.Minute)
|
|
continue
|
|
}
|
|
zurglog.Debugf("Reachable hosts (%d): %v", len(hosts), hosts)
|
|
break
|
|
}
|
|
}
|
|
|
|
rateLimiter := http.NewRateLimiter(config.GetAPIRateLimitPerMinute())
|
|
|
|
apiClient := http.NewHTTPClient(
|
|
config.GetToken(),
|
|
config.GetRetriesUntilFailed(), // default retries = 2
|
|
config.GetApiTimeoutSecs(), // default api timeout = 60
|
|
false, // no need for ipv6 support
|
|
[]string{}, // no optimal hosts needed
|
|
proxyURL,
|
|
rateLimiter,
|
|
log.Named("api_client"),
|
|
)
|
|
|
|
unrestrictClient := http.NewHTTPClient(
|
|
"",
|
|
config.GetRetriesUntilFailed(), // default retries = 2
|
|
config.GetDownloadTimeoutSecs(), // default download timeout = 10
|
|
false, // no need for ipv6 support
|
|
[]string{}, // no optimal hosts needed
|
|
proxyURL,
|
|
rateLimiter,
|
|
log.Named("unrestrict_client"),
|
|
)
|
|
|
|
downloadClient := http.NewHTTPClient(
|
|
"",
|
|
config.GetRetriesUntilFailed(),
|
|
config.GetDownloadTimeoutSecs(),
|
|
config.ShouldForceIPv6(),
|
|
hosts,
|
|
proxyURL,
|
|
nil,
|
|
log.Named("download_client"),
|
|
)
|
|
|
|
workerCount := config.GetNumberOfWorkers()
|
|
if workerCount < 20 {
|
|
workerCount = 20
|
|
}
|
|
workerPool, err := ants.NewPool(workerCount)
|
|
if err != nil {
|
|
zurglog.Errorf("Failed to create worker pool: %v", err)
|
|
os.Exit(1)
|
|
}
|
|
defer workerPool.Release()
|
|
|
|
torrentsRateLimiter := http.NewRateLimiter(config.GetTorrentsRateLimitPerMinute())
|
|
|
|
rd := realdebrid.NewRealDebrid(
|
|
apiClient,
|
|
unrestrictClient,
|
|
downloadClient,
|
|
workerPool,
|
|
torrentsRateLimiter,
|
|
config,
|
|
log.Named("realdebrid"),
|
|
)
|
|
rd.MonitorExpiredTokens()
|
|
|
|
premium.MonitorPremiumStatus(
|
|
workerPool,
|
|
rd,
|
|
zurglog,
|
|
)
|
|
|
|
hasFFprobe := true
|
|
_, err = exec.LookPath("ffprobe")
|
|
if err != nil {
|
|
hasFFprobe = false
|
|
zurglog.Warn("ffprobe not found in PATH (do you have ffmpeg installed?), you won't be able to perform media analysis")
|
|
}
|
|
|
|
torrentMgr := torrent.NewTorrentManager(
|
|
config,
|
|
rd,
|
|
workerPool,
|
|
hasFFprobe,
|
|
log.Named("manager"),
|
|
log.Named("repair"),
|
|
)
|
|
|
|
downloader := universal.NewDownloader(rd, workerPool)
|
|
downloader.StartResetBandwidthCountersJob()
|
|
|
|
router := chi.NewRouter()
|
|
handlers.AttachHandlers(
|
|
router,
|
|
downloader,
|
|
torrentMgr,
|
|
config,
|
|
rd,
|
|
workerPool,
|
|
hosts,
|
|
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)
|
|
}
|
|
}
|