package main import ( "context" "fmt" "io" "os" "sync" "git.luzifer.io/luzifer/publish-vod/pkg/config" "git.luzifer.io/luzifer/publish-vod/pkg/uploader" "github.com/cheggaaa/pb/v3" "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/Luzifer/rconfig/v2" ) var ( cfg = struct { Config string `flag:"config,c" default:"config.yaml" description:"Configuration for the uploaders"` LogLevel string `flag:"log-level" default:"info" description:"Log level (debug, info, warn, error, fatal)"` ValidateOnly bool `flag:"validate-only" default:"false" description:"Only execute validation and prepare functions, do not upload"` VersionAndExit bool `flag:"version" default:"false" description:"Prints current version and exits"` }{} version = "dev" ) func initApp() error { rconfig.AutoEnv(true) if err := rconfig.ParseAndValidate(&cfg); err != nil { return errors.Wrap(err, "parsing cli options") } l, err := logrus.ParseLevel(cfg.LogLevel) if err != nil { return errors.Wrap(err, "parsing log-level") } logrus.SetLevel(l) return nil } func main() { var err error if err = initApp(); err != nil { logrus.WithError(err).Fatal("initializing app") } if cfg.VersionAndExit { logrus.WithField("version", version).Info("publish-vod") os.Exit(0) } configFile, err := config.Load(cfg.Config) if err != nil { logrus.WithError(err).Fatal("loading config") } var ( ctx = context.Background() wg sync.WaitGroup ) var ( barPool = pb.NewPool() longestPrefix int ) for _, c := range configFile.Uploaders { u := uploaderByName(c.Type) if u == nil { logrus.Fatalf("unknown uploader %q", c.Type) } if err = u.ValidateConfig(c.Settings); err != nil { logrus.WithError(err).Fatalf("validating config entry %q", c.Name) } if err = u.Prepare(ctx, uploader.UploaderOpts{ Name: c.Name, Config: c.Settings, }); err != nil { logrus.WithError(err).Fatalf("preparing uploader %q", c.Name) } if l := len(c.Name); l > longestPrefix { longestPrefix = l } } if cfg.ValidateOnly { return } if len(rconfig.Args()) < 2 { //nolint:gomnd logrus.Fatal("Usage: publish-vod ") } fileName := rconfig.Args()[1] f, err := os.Open(fileName) if err != nil { logrus.WithError(err).Fatal("opening VoD") } defer f.Close() //nolint:errcheck // File is closed by process exit stat, err := f.Stat() if err != nil { logrus.WithError(err).Fatal("getting VoD stat") } for i := range configFile.Uploaders { wg.Add(1) bar := pb.New64(stat.Size()) bar.SetTemplate(pb.Full) barPool.Add(bar) go func(c config.UploaderConfig, bar *pb.ProgressBar) { defer wg.Done() bar.Set("prefix", fmt.Sprintf(fmt.Sprintf("%%-%ds", longestPrefix), c.Name)) if err = uploaderByName(c.Type).UploadFile(ctx, uploader.UploaderOpts{ Name: c.Name, Config: c.Settings, Filename: fileName, Content: io.NewSectionReader(f, 0, stat.Size()), Size: stat.Size(), ProgressBar: bar, FinalMessage: func(format string, opts ...any) { bar.SetTemplate(pb.ProgressBarTemplate(fmt.Sprintf(`{{ string . "prefix" }} %s`, fmt.Sprintf(format, opts...)))) }, }); err != nil { bar.SetTemplate(pb.ProgressBarTemplate(fmt.Sprintf(`{{ string . "prefix" }} ERR: %s`, err))) } }(configFile.Uploaders[i], bar) } barPool.Start() wg.Wait() barPool.Stop() }