diff --git a/cmd/caption/caption.go b/cmd/caption/caption.go index 790d849..564e175 100644 --- a/cmd/caption/caption.go +++ b/cmd/caption/caption.go @@ -22,6 +22,8 @@ var ( videoId string parts []string output string + tfmt string + tlang string ) var captionCmd = &cobra.Command{ diff --git a/cmd/caption/download.go b/cmd/caption/download.go new file mode 100644 index 0000000..a98d3be --- /dev/null +++ b/cmd/caption/download.go @@ -0,0 +1,38 @@ +package caption + +import ( + "github.com/eat-pray-ai/yutu/pkg/yutuber/caption" + "github.com/spf13/cobra" +) + +var downloadCmd = &cobra.Command{ + Use: "download", + Short: "Download caption", + Long: "Download caption from a video", + Run: func(cmd *cobra.Command, args []string) { + c := caption.NewCation( + caption.WithId(id), + caption.WithFile(file), + caption.WithTfmt(tfmt), + caption.WithTlang(tlang), + caption.WithOnBehalfOf(onBehalfOf), + caption.WithOnBehalfOfContentOwner(onBehalfOfContentOwner), + caption.WithService(nil), + ) + c.Download() + }, +} + +func init() { + captionCmd.AddCommand(downloadCmd) + + downloadCmd.Flags().StringVarP(&id, "id", "i", "", "ID of the caption") + downloadCmd.Flags().StringVarP(&file, "file", "f", "", "Path to save the caption file") + downloadCmd.Flags().StringVarP(&tfmt, "tfmt", "t", "", "sbv, srt or vtt") + downloadCmd.Flags().StringVarP(&tlang, "tlang", "l", "", "Translate the captions into this language") + downloadCmd.Flags().StringVarP(&onBehalfOf, "onBehalfOf", "b", "", "") + downloadCmd.Flags().StringVarP(&onBehalfOfContentOwner, "onBehalfOfContentOwner", "B", "", "") + + downloadCmd.MarkFlagRequired("id") + downloadCmd.MarkFlagRequired("file") +} diff --git a/pkg/yutuber/caption/caption.go b/pkg/yutuber/caption/caption.go index 0473a14..0ca2a52 100644 --- a/pkg/yutuber/caption/caption.go +++ b/pkg/yutuber/caption/caption.go @@ -6,17 +6,19 @@ import ( "github.com/eat-pray-ai/yutu/pkg/auth" "github.com/eat-pray-ai/yutu/pkg/utils" "google.golang.org/api/youtube/v3" + "io" "log" "os" ) var ( - service *youtube.Service - errOpenFile = errors.New("failed to open file") - errGetCaption = errors.New("failed to get caption") - errUpdateCaption = errors.New("failed to update caption") - errDeleteCaption = errors.New("failed to delete caption") - errInsertCaption = errors.New("failed to insert caption") + service *youtube.Service + errOpenFile = errors.New("failed to open file") + errGetCaption = errors.New("failed to get caption") + errUpdateCaption = errors.New("failed to update caption") + errDeleteCaption = errors.New("failed to delete caption") + errInsertCaption = errors.New("failed to insert caption") + errDownloadCaption = errors.New("failed to download caption") ) type caption struct { @@ -34,6 +36,8 @@ type caption struct { onBehalfOf string onBehalfOfContentOwner string videoId string + tfmt string + tlang string } type Caption interface { @@ -42,6 +46,7 @@ type Caption interface { Insert() Update() Delete() + Download() } type Option func(*caption) @@ -200,6 +205,42 @@ func (c *caption) Delete() { fmt.Printf("Caption %s deleted\n", c.id) } +func (c *caption) Download() { + call := service.Captions.Download(c.id) + if c.tfmt != "" { + call = call.Tfmt(c.tfmt) + } + if c.tlang != "" { + call = call.Tlang(c.tlang) + } + if c.onBehalfOf != "" { + call = call.OnBehalfOf(c.onBehalfOf) + } + if c.onBehalfOfContentOwner != "" { + call = call.OnBehalfOfContentOwner(c.onBehalfOfContentOwner) + } + + res, err := call.Download() + if err != nil { + log.Fatalln(errors.Join(errDownloadCaption, err)) + } + defer res.Body.Close() + body, err := io.ReadAll(res.Body) + if err != nil { + log.Fatalln(errors.Join(errDownloadCaption, err)) + } + + file, err := os.Create(c.file) + if err != nil { + log.Fatalln(errors.Join(errDownloadCaption, err)) + } + defer file.Close() + _, err = file.Write(body) + if err != nil { + log.Fatalln(errors.Join(errDownloadCaption, err)) + } +} + func WithId(id string) Option { return func(c *caption) { c.id = id @@ -294,6 +335,18 @@ func WithVideoId(videoId string) Option { } } +func WithTfmt(tfmt string) Option { + return func(c *caption) { + c.tfmt = tfmt + } +} + +func WithTlang(tlang string) Option { + return func(c *caption) { + c.tlang = tlang + } +} + func WithService(svc *youtube.Service) Option { return func(c *caption) { if svc != nil {