publish-vod/main.go
2024-03-27 18:26:13 +01:00

147 lines
3.3 KiB
Go

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>")
}
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()
}