115 lines
3.4 KiB
Go
115 lines
3.4 KiB
Go
/*
|
|
Copyright © 2024 Evan Fiordeliso <evan.fiordeliso@gmail.com>
|
|
*/
|
|
package cmd
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"log/slog"
|
|
"os"
|
|
|
|
"github.com/dgraph-io/badger/v2"
|
|
"github.com/spf13/cobra"
|
|
"github.com/spf13/viper"
|
|
"go.fifitido.net/ytdl-web/config"
|
|
"go.fifitido.net/ytdl-web/pkg/server"
|
|
"go.fifitido.net/ytdl-web/pkg/utils"
|
|
"go.fifitido.net/ytdl-web/pkg/ytdl"
|
|
"go.fifitido.net/ytdl-web/pkg/ytdl/cache"
|
|
)
|
|
|
|
var (
|
|
cfgFile string
|
|
cfg *config.Config
|
|
|
|
rootCmd = &cobra.Command{
|
|
Use: "ytdl-web",
|
|
Short: "A web frontend for yt-dlp",
|
|
Long: `YTDL Web is a web application that grabs the links to videos
|
|
from over a thousand websites using the yt-dlp project under the hood.`,
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
initLogging()
|
|
logger := slog.Default()
|
|
|
|
db, err := badger.Open(
|
|
badger.
|
|
DefaultOptions(cfg.Cache.DirPath).
|
|
WithLogger(utils.NewBadgerLogger(logger.With("module", "badger"))),
|
|
)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer db.Close()
|
|
|
|
cache := cache.NewDefaultMetadataCache(db)
|
|
yt := ytdl.NewYtdl(cfg, slog.Default(), cache)
|
|
ytdl.SetDefault(yt)
|
|
|
|
return server.ListenAndServe(
|
|
server.WithListenAddr(viper.GetString("http.listen")),
|
|
server.WithListenPort(viper.GetInt("http.port")),
|
|
server.WithLogger(logger.With("module", "server")),
|
|
)
|
|
},
|
|
}
|
|
)
|
|
|
|
func Execute() error {
|
|
return rootCmd.Execute()
|
|
}
|
|
|
|
func init() {
|
|
cobra.OnInitialize(initConfig)
|
|
|
|
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $XDG_CONFIG_HOME/ytdl-web/config.yml)")
|
|
|
|
rootCmd.PersistentFlags().IntP("port", "p", 8080, "port to listen on")
|
|
rootCmd.PersistentFlags().StringP("listen", "l", "", "address to listen on")
|
|
rootCmd.PersistentFlags().StringP("base-path", "b", "", "the base path, used when behind reverse proxy")
|
|
rootCmd.PersistentFlags().StringP("ytdlp-path", "y", "", "the path to the yt-dlp binary, used when it is not in $PATH")
|
|
rootCmd.PersistentFlags().BoolP("cookies-enabled", "C", false, "whether cookies are enabled")
|
|
rootCmd.PersistentFlags().StringP("cookies", "c", "", "the path to the cookies file")
|
|
|
|
viper.BindPFlag("http.port", rootCmd.PersistentFlags().Lookup("port"))
|
|
viper.BindPFlag("http.listen", rootCmd.PersistentFlags().Lookup("listen"))
|
|
viper.BindPFlag("http.basePath", rootCmd.PersistentFlags().Lookup("base-path"))
|
|
viper.BindPFlag("ytdlp.binaryPath", rootCmd.PersistentFlags().Lookup("ytdlp-path"))
|
|
viper.BindPFlag("cookies.enabled", rootCmd.PersistentFlags().Lookup("cookies-enabled"))
|
|
viper.BindPFlag("cookies.filePath", rootCmd.PersistentFlags().Lookup("cookies"))
|
|
}
|
|
|
|
func initConfig() {
|
|
var err error
|
|
if cfgFile != "" {
|
|
cfg, err = config.LoadConfig(cfgFile)
|
|
} else {
|
|
cfg, err = config.LoadConfig()
|
|
}
|
|
|
|
notFound := &viper.ConfigFileNotFoundError{}
|
|
switch {
|
|
case err != nil && !errors.As(err, notFound):
|
|
cobra.CheckErr(err)
|
|
case err != nil && errors.As(err, notFound):
|
|
// The config file is optional, we shouldn't exit when the config is not found
|
|
break
|
|
default:
|
|
fmt.Fprintln(os.Stderr, "Using config file:", viper.ConfigFileUsed())
|
|
}
|
|
}
|
|
|
|
func initLogging() {
|
|
if cfg.IsProduction() {
|
|
slog.SetDefault(slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
|
|
AddSource: true,
|
|
Level: slog.LevelInfo,
|
|
})))
|
|
} else {
|
|
slog.SetDefault(slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
|
|
AddSource: true,
|
|
Level: slog.LevelDebug,
|
|
})))
|
|
}
|
|
}
|