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:
2026-03-19 00:37:46 +09:00
parent 76485e7708
commit 7ff2b4feb1

139
cmd/streamdata/main.go Normal file
View 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)
}
})
}