/* Copyright © 2024 Evan Fiordeliso */ package main import ( "flag" "log/slog" "net/http" "os" "time" "github.com/dgraph-io/badger/v2" "github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5/middleware" slogchi "github.com/samber/slog-chi" "go.fifitido.net/ytdl-web/pkg/config" "go.fifitido.net/ytdl-web/pkg/serverctx" "go.fifitido.net/ytdl-web/pkg/views" "go.fifitido.net/ytdl-web/pkg/ytdl" "go.fifitido.net/ytdl-web/pkg/ytdl/cache" ) var ( env = config.String("env", "production", "the environment to run") listenAddr = config.String("listen", ":8080", "address to listen on") basePath = config.String("base_path", "/", "the base path, used when behind reverse proxy") ytdlpPath = config.String("ytdlp.binary", "", "path to yt-dlp executable") cacheTTL = config.Duration("cache.ttl", time.Hour, "the TTL for the cache") cacheDir = config.String("cache.dir", "", "the directory to store the cache") cookies = config.Bool("cookies", false, "whether cookies are enabled") cookiesPath = config.String("cookies.path", "", "the path to the cookies file") cookiesBrowser = config.String("cookies.browser", "", "the browser to use for cookies") cookiesBrowserKeyring = config.String("cookies.browser.keyring", "", "the keyring to use for cookies") cookiesBrowserProfile = config.String("cookies.browser.profile", "", "the profile to use for cookies") cookiesBrowserContainer = config.String("cookies.browser.container", "", "the container to use for cookies") ) func main() { flag.Parse() logger := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{ AddSource: true, Level: slog.LevelInfo, })) if env() == "development" { logger = slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{ AddSource: true, Level: slog.LevelDebug, })) } slog.SetDefault(logger) db, err := badger.Open( badger. DefaultOptions(cacheDir()). WithLogger(&badgerLogger{logger: logger.With("module", "badger")}), ) if err != nil { os.Exit(1) } defer db.Close() cache := cache.NewDefaultMetadataCache(db, cacheTTL()) ytdl.SetDefault( ytdl.NewYtdl(&ytdl.Config{ BinaryPath: ytdlpPath(), CookiesEnabled: cookies(), CookiesFilePath: cookiesPath(), CookiesBrowser: cookiesBrowser(), CookiesBrowserKeyring: cookiesBrowserKeyring(), CookiesBrowserProfile: cookiesBrowserProfile(), CookiesBrowserContainer: cookiesBrowserContainer(), }, logger, cache), ) r := chi.NewRouter() r.Use( serverctx.Middleware(basePath()), middleware.RequestID, middleware.RealIP, slogchi.New(logger), middleware.Recoverer, ) r.Route(basePath(), func(r chi.Router) { r.Get("/", views.Handler(views.Home(nil))) r.Route("/download", func(r chi.Router) { r.Get("/", download) r.Head("/proxy", proxyDownload) r.Get("/proxy", proxyDownload) }) }) logger.Info("Starting HTTP server", slog.String("listen", listenAddr())) if err := http.ListenAndServe(listenAddr(), r); err != nil { logger.Error("failed to serve website", slog.Any("error", err)) os.Exit(1) } }