cmd/streamdata: vod creation tool
This prompts the user for metadata and downloads the asset. Signed-off-by: Yonah <contrib@gensokyo.uk>
This commit is contained in:
139
cmd/streamdata/main.go
Normal file
139
cmd/streamdata/main.go
Normal file
@@ -0,0 +1,139 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"git.gensokyo.uk/yonah/streamdata"
|
||||
"hakurei.app/command"
|
||||
)
|
||||
|
||||
const programName = "streamdata"
|
||||
|
||||
func main() {
|
||||
log.SetFlags(0)
|
||||
log.SetPrefix(programName + ": ")
|
||||
|
||||
var channel *streamdata.Channel
|
||||
ctx, stop := signal.NotifyContext(context.Background(),
|
||||
syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP)
|
||||
defer stop()
|
||||
|
||||
var (
|
||||
flagBase string
|
||||
)
|
||||
c := command.New(os.Stderr, log.Printf, programName, func([]string) (err error) {
|
||||
if flagBase != "" {
|
||||
channel, err = streamdata.Open(flagBase)
|
||||
}
|
||||
return
|
||||
}).Flag(
|
||||
&flagBase,
|
||||
"d", command.StringFlag(""),
|
||||
"Channel directory to open",
|
||||
)
|
||||
|
||||
c.NewCommand(
|
||||
"add",
|
||||
"Add a VOD to the channel",
|
||||
func(args []string) error {
|
||||
if channel == nil {
|
||||
return errors.New("add requires a channel selected")
|
||||
}
|
||||
|
||||
if len(args) != 1 {
|
||||
return errors.New("add requires 1 argument")
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, args[0], nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
name := path.Base(req.URL.Path)
|
||||
if !strings.HasSuffix(name, streamdata.ChannelVODSuffix) {
|
||||
return errors.New("file name missing expected suffix")
|
||||
}
|
||||
name = name[:len(name)-len(streamdata.ChannelVODSuffix)]
|
||||
|
||||
var ident streamdata.Ident
|
||||
if err = ident.UnmarshalText(
|
||||
unsafe.Slice(unsafe.StringData(name), len(name)),
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return channel.Add(&ident, func(
|
||||
v *streamdata.VOD,
|
||||
w io.Writer,
|
||||
) (err error) {
|
||||
defer toErr(&err)
|
||||
isattyStd()
|
||||
br := bufio.NewReader(os.Stdin)
|
||||
|
||||
v.Title = require(promptTrimNoEmpty(br, "Title: "))
|
||||
v.Category = require(prompt(br, "Category: "))
|
||||
|
||||
now := time.Now()
|
||||
year := require(promptUintFallbackBounds(
|
||||
br, "Year: ",
|
||||
1970, uint64(now.Year()),
|
||||
uint64(now.Year()),
|
||||
))
|
||||
|
||||
ubMonth := time.December
|
||||
if year == uint64(now.Year()) {
|
||||
ubMonth = now.Month()
|
||||
}
|
||||
month := require(promptUintFallbackBounds(
|
||||
br, "Month: ",
|
||||
uint64(time.January), uint64(ubMonth),
|
||||
uint64(now.Month()),
|
||||
))
|
||||
day := require(promptUintFallbackBounds(
|
||||
br, "Day:",
|
||||
1, 31,
|
||||
uint64(now.Day()),
|
||||
))
|
||||
v.Date = time.Date(
|
||||
int(year), time.Month(month), int(day),
|
||||
0, 0, 0, 0,
|
||||
time.UTC,
|
||||
)
|
||||
|
||||
var resp *http.Response
|
||||
if resp, err = http.DefaultClient.Do(req); err != nil {
|
||||
return
|
||||
} else {
|
||||
_, err = copyProgress(w, resp.Body, resp.ContentLength)
|
||||
if closeErr := resp.Body.Close(); err == nil {
|
||||
err = closeErr
|
||||
}
|
||||
}
|
||||
return
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
c.MustParse(os.Args[1:], func(err error) {
|
||||
if channel != nil {
|
||||
if closeErr := channel.Close(); closeErr != nil {
|
||||
log.Println(closeErr)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user