🥅 Improve err handling

This commit is contained in:
OpenWaygate committed 2025-06-25 23:54:30 +08:00
1 parent 50fd850277
commit 575e4a947c
76 files changed
+918 -504

No files matched your search

+1 -1
View File
@@ -72,7 +72,7 @@ var listCmd = &cobra.Command{
err := run(cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %s\n", err.Error())
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+1 -1
View File
@@ -29,7 +29,7 @@ var downloadCmd = &cobra.Command{
err := c.Download(cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %s\n", err.Error())
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+1 -1
View File
@@ -36,7 +36,7 @@ var insertCmd = &cobra.Command{
err := c.Insert(output, cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %s\n", err.Error())
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+1 -1
View File
@@ -28,7 +28,7 @@ var listCmd = &cobra.Command{
err := c.List(parts, output, cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %s\n", err.Error())
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+1 -1
View File
@@ -36,7 +36,7 @@ var updateCmd = &cobra.Command{
err := c.Update(output, cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %s\n", err.Error())
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -30,7 +30,12 @@ var listCmd = &cobra.Command{
channel.WithOnBehalfOfContentOwner(onBehalfOfContentOwner),
channel.WithService(nil),
)
c.List(parts, output)
err := c.List(parts, output, cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -26,7 +26,12 @@ var updateCmd = &cobra.Command{
channel.WithTitle(title),
channel.WithService(nil),
)
c.Update(output)
err := c.Update(output, cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -17,7 +17,12 @@ var insertCmd = &cobra.Command{
channelBanner.WithOnBehalfOfContentOwnerChannel(onBehalfOfContentOwnerChannel),
channelBanner.WithService(nil),
)
cb.Insert(output)
err := cb.Insert(output, cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -21,7 +21,12 @@ var deleteCmd = &cobra.Command{
channelSection.WithOnBehalfOfContentOwner(onBehalfOfContentOwner),
channelSection.WithService(nil),
)
cs.Delete()
err := cs.Delete(cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -24,7 +24,12 @@ var listCmd = &cobra.Command{
channelSection.WithOnBehalfOfContentOwner(onBehalfOfContentOwner),
channelSection.WithService(nil),
)
cs.List(parts, output)
err := cs.List(parts, output, cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -19,7 +19,12 @@ var deleteCmd = &cobra.Command{
comment.WithIDs(ids),
comment.WithService(nil),
)
c.Delete()
err := c.Delete(cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -26,7 +26,12 @@ var insertCmd = &cobra.Command{
comment.WithVideoId(videoId),
comment.WithService(nil),
)
c.Insert(output)
err := c.Insert(output, cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -24,7 +24,12 @@ var listCmd = &cobra.Command{
comment.WithTextFormat(textFormat),
comment.WithService(nil),
)
c.List(parts, output)
err := c.List(parts, output, cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -20,7 +20,12 @@ var markAsSpamCmd = &cobra.Command{
comment.WithIDs(ids),
comment.WithService(nil),
)
c.MarkAsSpam(output)
err := c.MarkAsSpam(output, cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -21,7 +21,12 @@ var setModerationStatusCmd = &cobra.Command{
comment.WithModerationStatus(moderationStatus),
comment.WithBanAuthor(banAuthor),
)
c.SetModerationStatus(output)
err := c.SetModerationStatus(output, cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -24,7 +24,12 @@ var updateCmd = &cobra.Command{
comment.WithViewerRating(viewerRating),
comment.WithService(nil),
)
c.Update(output)
err := c.Update(output, cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -23,7 +23,12 @@ var insertCmd = &cobra.Command{
commentThread.WithVideoId(videoId),
commentThread.WithService(nil),
)
ct.Insert(output)
err := ct.Insert(output, cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -28,7 +28,12 @@ var listCmd = &cobra.Command{
commentThread.WithVideoId(videoId),
commentThread.WithService(nil),
)
ct.List(parts, output)
err := ct.List(parts, output, cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -13,7 +13,12 @@ var listCmd = &cobra.Command{
i := i18nLanguage.NewI18nLanguage(
i18nLanguage.WithHl(hl), i18nLanguage.WithService(nil),
)
i.List(parts, output)
err := i.List(parts, output, cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -13,7 +13,12 @@ var listCmd = &cobra.Command{
i := i18nRegion.NewI18nRegion(
i18nRegion.WithHl(hl), i18nRegion.WithService(nil),
)
i.List(parts, output)
err := i.List(parts, output, cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -17,7 +17,12 @@ var listCmd = &cobra.Command{
member.WithMode(mode),
member.WithService(nil),
)
m.List(parts, output)
err := m.List(parts, output, cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -11,7 +11,12 @@ var listCmd = &cobra.Command{
Long: long,
Run: func(cmd *cobra.Command, args []string) {
m := membershipsLevel.NewMembershipsLevel(membershipsLevel.WithService(nil))
m.List(parts, output)
err := m.List(parts, output, cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -21,7 +21,12 @@ var deleteCmd = &cobra.Command{
playlist.WithOnBehalfOfContentOwner(onBehalfOfContentOwner),
playlist.WithService(nil),
)
p.Delete()
err := p.Delete(cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -26,7 +26,12 @@ var insertCmd = &cobra.Command{
playlist.WithPrivacy(privacy),
playlist.WithService(nil),
)
p.Insert(output)
err := p.Insert(output, cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -28,7 +28,12 @@ var listCmd = &cobra.Command{
playlist.WithOnBehalfOfContentOwnerChannel(onBehalfOfContentOwnerChannel),
playlist.WithService(nil),
)
p.List(parts, output)
err := p.List(parts, output, cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -26,7 +26,12 @@ var updateCmd = &cobra.Command{
playlist.WithPrivacy(privacy),
playlist.WithService(nil),
)
p.Update(output)
err := p.Update(output, cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -20,7 +20,12 @@ var deleteCmd = &cobra.Command{
playlistImage.WithOnBehalfOfContentOwner(onBehalfOfContentOwner),
playlistImage.WithService(nil),
)
pi.Delete()
err := pi.Delete(cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -24,7 +24,12 @@ var insertCmd = &cobra.Command{
playlistImage.WithWidth(width),
playlistImage.WithService(nil),
)
pi.Insert(output)
err := pi.Insert(output, cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -23,7 +23,12 @@ var listCmd = &cobra.Command{
playlistImage.WithMaxResults(maxResults),
playlistImage.WithService(nil),
)
pi.List(parts, output)
err := pi.List(parts, output, cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -23,7 +23,12 @@ var updateCmd = &cobra.Command{
playlistImage.WithWidth(width),
playlistImage.WithService(nil),
)
pi.Update(output)
err := pi.Update(output, cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -21,7 +21,12 @@ var deleteCmd = &cobra.Command{
playlistItem.WithOnBehalfOfContentOwner(onBehalfOfContentOwner),
playlistItem.WithService(nil),
)
pi.Delete()
err := pi.Delete(cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -30,7 +30,12 @@ var insertCmd = &cobra.Command{
playlistItem.WithOnBehalfOfContentOwner(onBehalfOfContentOwner),
playlistItem.WithService(nil),
)
pi.Insert(output)
err := pi.Insert(output, cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -26,7 +26,12 @@ var listCmd = &cobra.Command{
playlistItem.WithOnBehalfOfContentOwner(onBehalfOfContentOwner),
playlistItem.WithService(nil),
)
pi.List(parts, output)
err := pi.List(parts, output, cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -25,7 +25,12 @@ var updateCmd = &cobra.Command{
playlistItem.WithOnBehalfOfContentOwner(onBehalfOfContentOwner),
playlistItem.WithService(nil),
)
pi.Update(output)
err := pi.Update(output, cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -42,7 +42,12 @@ var listCmd = &cobra.Command{
search.WithVideoType(videoType),
search.WithService(nil),
)
s.List(parts, output)
err := s.List(parts, output, cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -19,7 +19,12 @@ var deleteCmd = &cobra.Command{
s := subscription.NewSubscription(
subscription.WithIDs(ids), subscription.WithService(nil),
)
s.Delete()
err := s.Delete(cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -24,7 +24,12 @@ var insertCmd = &cobra.Command{
subscription.WithTitle(title),
subscription.WithService(nil),
)
s.Insert(output)
err := s.Insert(output, cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -31,7 +31,12 @@ var listCmd = &cobra.Command{
subscription.WithOrder(order),
subscription.WithService(nil),
)
s.List(parts, output)
err := s.List(parts, output, cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -15,7 +15,12 @@ var listCmd = &cobra.Command{
superChatEvent.WithMaxResults(maxResults),
superChatEvent.WithService(nil),
)
sc.List(parts, output)
err := sc.List(parts, output, cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -15,7 +15,12 @@ var setCmd = &cobra.Command{
thumbnail.WithVideoId(videoId),
thumbnail.WithService(nil),
)
t.Set(output)
err := t.Set(output, cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -17,7 +17,12 @@ var deleteCmd = &cobra.Command{
Long: deleteLong,
Run: func(cmd *cobra.Command, args []string) {
v := video.NewVideo(video.WithIDs(ids))
v.Delete()
err := v.Delete(cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -22,7 +22,12 @@ var getRatingCmd = &cobra.Command{
video.WithOnBehalfOfContentOwner(onBehalfOfContentOwner),
video.WithService(nil),
)
v.GetRating(output)
err := v.GetRating(output, cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -40,7 +40,12 @@ var insertCmd = &cobra.Command{
video.WithOnBehalfOfContentOwnerChannel(onBehalfOfContentOwnerChannel),
video.WithService(nil),
)
v.Insert(output)
err := v.Insert(output, cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -32,7 +32,12 @@ var listCmd = &cobra.Command{
video.WithRating(rating),
video.WithService(nil),
)
v.List(parts, output)
err := v.List(parts, output, cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -22,7 +22,12 @@ var rateCmd = &cobra.Command{
video.WithRating(rating),
video.WithService(nil),
)
v.Rate()
err := v.Rate(cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -26,7 +26,12 @@ var reportAbuseCmd = &cobra.Command{
video.WithOnBehalfOfContentOwner(onBehalfOfContentOwner),
video.WithService(nil),
)
v.ReportAbuse()
err := v.ReportAbuse(cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -32,7 +32,12 @@ var updateCmd = &cobra.Command{
video.WithEmbeddable(embeddable),
video.WithService(nil),
)
v.Update(output)
err := v.Update(output, cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -14,7 +14,12 @@ var listCmd = &cobra.Command{
videoAbuseReportReason.WithHL(hl),
videoAbuseReportReason.WithService(nil),
)
va.List(parts, output)
err := va.List(parts, output, cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -16,7 +16,12 @@ var listCmd = &cobra.Command{
videoCategory.WithRegionCode(regionCode),
videoCategory.WithService(nil),
)
vc.List(parts, output)
err := vc.List(parts, output, cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -25,7 +25,12 @@ var setCmd = &cobra.Command{
watermark.WithOnBehalfOfContentOwner(onBehalfOfContentOwner),
watermark.WithService(nil),
)
w.Set()
err := w.Set(cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+6 -1
View File
@@ -19,7 +19,12 @@ var unsetCmd = &cobra.Command{
watermark.WithChannelId(channelId),
watermark.WithService(nil),
)
w.Unset()
err := w.Unset(cmd.OutOrStdout())
if err != nil {
_ = cmd.Help()
cmd.PrintErrf("Error: %v\n", err)
}
},
}
+8
View File
@@ -0,0 +1,8 @@
load("@rules_go//go:def.bzl", "go_library")
go_library(
name = "pkg",
srcs = ["interface.go"],
importpath = "github.com/eat-pray-ai/yutu/pkg",
visibility = ["//visibility:public"],
)
+3 -3
View File
@@ -26,7 +26,7 @@ type activity struct {
type Activity interface {
List([]string, string, io.Writer) error
get([]string) ([]*youtube.Activity, error)
Get([]string) ([]*youtube.Activity, error)
}
type Option func(*activity)
@@ -41,7 +41,7 @@ func NewActivity(opts ...Option) Activity {
return a
}
func (a *activity) get(parts []string) ([]*youtube.Activity, error) {
func (a *activity) Get(parts []string) ([]*youtube.Activity, error) {
call := service.Activities.List(parts)
if a.ChannelId != "" {
call = call.ChannelId(a.ChannelId)
@@ -83,7 +83,7 @@ func (a *activity) get(parts []string) ([]*youtube.Activity, error) {
func (a *activity) List(
parts []string, output string, writer io.Writer,
) error {
activities, err := a.get(parts)
activities, err := a.Get(parts)
if err != nil {
return err
}
+5 -5
View File
@@ -39,7 +39,7 @@ type caption struct {
}
type Caption interface {
get(parts []string) ([]*youtube.Caption, error) // todo: return error
Get(parts []string) ([]*youtube.Caption, error) // todo: return error
List(parts []string, output string, writer io.Writer) error
Insert(output string, writer io.Writer) error
Update(output string, writer io.Writer) error
@@ -57,7 +57,7 @@ func NewCation(opts ...Option) Caption {
return c
}
func (c *caption) get(parts []string) ([]*youtube.Caption, error) {
func (c *caption) Get(parts []string) ([]*youtube.Caption, error) {
call := service.Captions.List(parts, c.VideoId)
if len(c.IDs) > 0 {
call = call.Id(c.IDs...)
@@ -78,7 +78,7 @@ func (c *caption) get(parts []string) ([]*youtube.Caption, error) {
}
func (c *caption) List(parts []string, output string, writer io.Writer) error {
captions, err := c.get(parts)
captions, err := c.Get(parts)
if err != nil {
return err
}
@@ -145,7 +145,7 @@ func (c *caption) Insert(output string, writer io.Writer) error {
}
func (c *caption) Update(output string, writer io.Writer) error {
captions, err := c.get([]string{"snippet"})
captions, err := c.Get([]string{"snippet"})
if err != nil {
return errors.Join(errUpdateCaption, err)
}
@@ -275,7 +275,7 @@ func (c *caption) Download(writer io.Writer) error {
return errors.Join(errDownloadCaption, err)
}
fmt.Printf("Caption %s downloaded to %s\n", c.IDs[0], c.File)
_, _ = fmt.Fprintf(writer, "Caption %s downloaded to %s\n", c.IDs[0], c.File)
return nil
}
+33 -22
View File
@@ -3,10 +3,9 @@ package channel
import (
"errors"
"fmt"
"log"
"github.com/eat-pray-ai/yutu/pkg/auth"
"github.com/eat-pray-ai/yutu/pkg/utils"
"io"
"google.golang.org/api/youtube/v3"
)
@@ -37,9 +36,9 @@ type channel struct {
}
type Channel interface {
List([]string, string)
Update(output string)
get([]string) []*youtube.Channel
List([]string, string, io.Writer) error
Update(string, io.Writer) error
Get([]string) ([]*youtube.Channel, error)
}
type Option func(*channel)
@@ -54,7 +53,7 @@ func NewChannel(opts ...Option) Channel {
return c
}
func (c *channel) get(parts []string) []*youtube.Channel {
func (c *channel) Get(parts []string) ([]*youtube.Channel, error) {
call := service.Channels.List(parts)
if c.CategoryId != "" {
call = call.CategoryId(c.CategoryId)
@@ -99,31 +98,43 @@ func (c *channel) get(parts []string) []*youtube.Channel {
res, err := call.Do()
if err != nil {
utils.PrintJSON(c, nil)
log.Fatalln(errors.Join(errGetChannel, err))
return nil, errors.Join(errGetChannel, err)
}
return res.Items
return res.Items, nil
}
func (c *channel) List(parts []string, output string) {
channels := c.get(parts)
func (c *channel) List(parts []string, output string, writer io.Writer) error {
channels, err := c.Get(parts)
if err != nil {
return err
}
switch output {
case "json":
utils.PrintJSON(channels, nil)
utils.PrintJSON(channels, writer)
case "yaml":
utils.PrintYAML(channels, nil)
utils.PrintYAML(channels, writer)
default:
fmt.Println("ID\tTitle")
_, _ = fmt.Fprintln(writer, "ID\tTitle")
for _, channel := range channels {
fmt.Printf("%s\t%s\n", channel.Id, channel.Snippet.Title)
_, _ = fmt.Fprintf(writer, "%s\t%s\n", channel.Id, channel.Snippet.Title)
}
}
return nil
}
func (c *channel) Update(output string) {
func (c *channel) Update(output string, writer io.Writer) error {
parts := []string{"snippet"}
cha := c.get(parts)[0]
channels, err := c.Get(parts)
if err != nil {
return errors.Join(errUpdateChannel, err)
}
if len(channels) == 0 {
return errGetChannel
}
cha := channels[0]
if c.Country != "" {
cha.Snippet.Country = c.Country
}
@@ -143,19 +154,19 @@ func (c *channel) Update(output string) {
call := service.Channels.Update(parts, cha)
res, err := call.Do()
if err != nil {
utils.PrintJSON(c, nil)
log.Fatalln(errors.Join(errUpdateChannel, err))
return errors.Join(errUpdateChannel, err)
}
switch output {
case "json":
utils.PrintJSON(res, nil)
utils.PrintJSON(res, writer)
case "yaml":
utils.PrintYAML(res, nil)
utils.PrintYAML(res, writer)
case "silent":
default:
fmt.Printf("Channel updated: %s\n", res.Id)
_, _ = fmt.Fprintf(writer, "Channel updated: %s\n", res.Id)
}
return nil
}
func WithCategoryId(categoryId string) Option {
+9 -10
View File
@@ -6,7 +6,7 @@ import (
"github.com/eat-pray-ai/yutu/pkg/auth"
"github.com/eat-pray-ai/yutu/pkg/utils"
"google.golang.org/api/youtube/v3"
"log"
"io"
"os"
)
@@ -24,7 +24,7 @@ type channelBanner struct {
}
type ChannelBanner interface {
Insert(output string)
Insert(string, io.Writer) error
}
type Option func(banner *channelBanner)
@@ -39,11 +39,10 @@ func NewChannelBanner(opts ...Option) ChannelBanner {
return cb
}
func (cb *channelBanner) Insert(output string) {
func (cb *channelBanner) Insert(output string, writer io.Writer) error {
file, err := os.Open(cb.File)
if err != nil {
utils.PrintJSON(cb, nil)
log.Fatalln(errors.Join(errInsertChannelBanner, err))
return errors.Join(errInsertChannelBanner, err)
}
defer file.Close()
cbr := &youtube.ChannelBannerResource{}
@@ -58,19 +57,19 @@ func (cb *channelBanner) Insert(output string) {
res, err := call.Do()
if err != nil {
utils.PrintJSON(cb, nil)
log.Fatalln(errors.Join(errInsertChannelBanner, err))
return errors.Join(errInsertChannelBanner, err)
}
switch output {
case "json":
utils.PrintJSON(res, nil)
utils.PrintJSON(res, writer)
case "yaml":
utils.PrintYAML(res, nil)
utils.PrintYAML(res, writer)
case "silent":
default:
fmt.Printf("ChannelBanner inserted: %s\n", res.Url)
_, _ = fmt.Fprintf(writer, "ChannelBanner inserted: %s\n", res.Url)
}
return nil
}
func WithChannelId(channelId string) Option {
+27 -19
View File
@@ -6,7 +6,7 @@ import (
"github.com/eat-pray-ai/yutu/pkg/auth"
"github.com/eat-pray-ai/yutu/pkg/utils"
"google.golang.org/api/youtube/v3"
"log"
"io"
)
var (
@@ -24,11 +24,11 @@ type channelSection struct {
}
type ChannelSection interface {
get(parts []string) []*youtube.ChannelSection
List(parts []string, output string)
Get([]string) ([]*youtube.ChannelSection, error)
List([]string, string, io.Writer) error
Delete(writer io.Writer) error
// Update()
// Insert()
Delete()
}
type Option func(*channelSection)
@@ -42,7 +42,9 @@ func NewChannelSection(opts ...Option) ChannelSection {
return cs
}
func (cs *channelSection) get(parts []string) []*youtube.ChannelSection {
func (cs *channelSection) Get(parts []string) (
[]*youtube.ChannelSection, error,
) {
call := service.ChannelSections.List(parts)
if len(cs.IDs) > 0 {
call = call.Id(cs.IDs...)
@@ -62,31 +64,37 @@ func (cs *channelSection) get(parts []string) []*youtube.ChannelSection {
res, err := call.Do()
if err != nil {
utils.PrintJSON(cs, nil)
log.Fatalln(errors.Join(errGetChannelSection, err))
return nil, errors.Join(errGetChannelSection, err)
}
return res.Items
return res.Items, nil
}
func (cs *channelSection) List(parts []string, output string) {
channelSections := cs.get(parts)
func (cs *channelSection) List(
parts []string, output string, writer io.Writer,
) error {
channelSections, err := cs.Get(parts)
if err != nil {
return err
}
switch output {
case "json":
utils.PrintJSON(channelSections, nil)
utils.PrintJSON(channelSections, writer)
case "yaml":
utils.PrintYAML(channelSections, nil)
utils.PrintYAML(channelSections, writer)
default:
fmt.Println("ID\tChannelID\tTitle")
_, _ = fmt.Fprintln(writer, "ID\tChannelID\tTitle")
for _, channelSection := range channelSections {
fmt.Printf(
"%s\t%s\t%s\n", channelSection.Id,
_, _ = fmt.Fprintf(
writer, "%s\t%s\t%s\n", channelSection.Id,
channelSection.Snippet.ChannelId, channelSection.Snippet.Title,
)
}
}
return nil
}
func (cs *channelSection) Delete() {
func (cs *channelSection) Delete(writer io.Writer) error {
for _, id := range cs.IDs {
call := service.ChannelSections.Delete(id)
if cs.OnBehalfOfContentOwner != "" {
@@ -95,12 +103,12 @@ func (cs *channelSection) Delete() {
err := call.Do()
if err != nil {
utils.PrintJSON(cs, nil)
log.Fatalln(errors.Join(errDeleteChannelSection, err))
return errors.Join(errDeleteChannelSection, err)
}
fmt.Printf("Channel section %s deleted\n", id)
_, _ = fmt.Fprintf(writer, "Channel section %s deleted\n", id)
}
return nil
}
func WithIDs(ids []string) Option {
+62 -48
View File
@@ -6,7 +6,7 @@ import (
"github.com/eat-pray-ai/yutu/pkg/auth"
"github.com/eat-pray-ai/yutu/pkg/utils"
"google.golang.org/api/youtube/v3"
"log"
"io"
)
var (
@@ -35,13 +35,13 @@ type comment struct {
}
type Comment interface {
get([]string) []*youtube.Comment
List([]string, string)
Insert(output string)
Update(output string)
Delete()
MarkAsSpam(output string)
SetModerationStatus(output string)
Get([]string) ([]*youtube.Comment, error)
List([]string, string, io.Writer) error
Insert(string, io.Writer) error
Update(string, io.Writer) error
Delete(io.Writer) error
MarkAsSpam(string, io.Writer) error
SetModerationStatus(string, io.Writer) error
}
type Option func(*comment)
@@ -56,7 +56,7 @@ func NewComment(opts ...Option) Comment {
return c
}
func (c *comment) get(parts []string) []*youtube.Comment {
func (c *comment) Get(parts []string) ([]*youtube.Comment, error) {
call := service.Comments.List(parts)
if c.IDs[0] != "" {
@@ -78,29 +78,35 @@ func (c *comment) get(parts []string) []*youtube.Comment {
res, err := call.Do()
if err != nil {
utils.PrintJSON(c, nil)
log.Fatalln(errors.Join(errGetComment, err))
return nil, errors.Join(errGetComment, err)
}
return res.Items
return res.Items, nil
}
func (c *comment) List(parts []string, output string) {
comments := c.get(parts)
func (c *comment) List(parts []string, output string, writer io.Writer) error {
comments, err := c.Get(parts)
if err != nil {
return err
}
switch output {
case "json":
utils.PrintJSON(comments, nil)
utils.PrintJSON(comments, writer)
case "yaml":
utils.PrintYAML(comments, nil)
utils.PrintYAML(comments, writer)
default:
fmt.Println("ID\tTextDisplay")
_, _ = fmt.Fprintln(writer, "ID\tTextDisplay")
for _, comment := range comments {
fmt.Printf("%s\t%s\n", comment.Id, comment.Snippet.TextDisplay)
_, _ = fmt.Fprintf(
writer, "%s\t%s\n", comment.Id, comment.Snippet.TextDisplay,
)
}
}
return nil
}
func (c *comment) Insert(output string) {
func (c *comment) Insert(output string, writer io.Writer) error {
comment := &youtube.Comment{
Snippet: &youtube.CommentSnippet{
AuthorChannelId: &youtube.CommentSnippetAuthorChannelId{
@@ -120,24 +126,31 @@ func (c *comment) Insert(output string) {
call := service.Comments.Insert([]string{"snippet"}, comment)
res, err := call.Do()
if err != nil {
utils.PrintJSON(c, nil)
log.Fatalln(errors.Join(errInsertComment, err))
return errors.Join(errInsertComment, err)
}
switch output {
case "json":
utils.PrintJSON(res, nil)
utils.PrintJSON(res, writer)
case "yaml":
utils.PrintYAML(res, nil)
utils.PrintYAML(res, writer)
case "silent":
default:
fmt.Printf("Comment inserted: %s\n", res.Id)
_, _ = fmt.Fprintf(writer, "Comment inserted: %s\n", res.Id)
}
return nil
}
func (c *comment) Update(output string) {
comment := c.get([]string{"id", "snippet"})[0]
func (c *comment) Update(output string, writer io.Writer) error {
comments, err := c.Get([]string{"id", "snippet"})
if err != nil {
return errors.Join(errUpdateComment, err)
}
if len(comments) == 0 {
return errGetComment
}
comment := comments[0]
if c.CanRate != nil {
comment.Snippet.CanRate = *c.CanRate
}
@@ -153,41 +166,41 @@ func (c *comment) Update(output string) {
call := service.Comments.Update([]string{"snippet"}, comment)
res, err := call.Do()
if err != nil {
utils.PrintJSON(c, nil)
log.Fatalln(errors.Join(errUpdateComment, err))
return errors.Join(errUpdateComment, err)
}
switch output {
case "json":
utils.PrintJSON(res, nil)
utils.PrintJSON(res, writer)
case "yaml":
utils.PrintYAML(res, nil)
utils.PrintYAML(res, writer)
case "silent":
default:
fmt.Printf("Comment updated: %s\n", res.Id)
_, _ = fmt.Fprintf(writer, "Comment updated: %s\n", res.Id)
}
return nil
}
func (c *comment) MarkAsSpam(output string) {
func (c *comment) MarkAsSpam(output string, writer io.Writer) error {
call := service.Comments.MarkAsSpam(c.IDs)
err := call.Do()
if err != nil {
utils.PrintJSON(c, nil)
log.Fatalln(errors.Join(errMarkAsSpam, err))
return errors.Join(errMarkAsSpam, err)
}
switch output {
case "json":
utils.PrintJSON(c, nil)
utils.PrintJSON(c, writer)
case "yaml":
utils.PrintYAML(c, nil)
utils.PrintYAML(c, writer)
case "silent":
default:
fmt.Printf("Comment marked as spam: %s\n", c.IDs)
_, _ = fmt.Fprintf(writer, "Comment marked as spam: %s\n", c.IDs)
}
return nil
}
func (c *comment) SetModerationStatus(output string) {
func (c *comment) SetModerationStatus(output string, writer io.Writer) error {
call := service.Comments.SetModerationStatus(c.IDs, c.ModerationStatus)
if c.BanAuthor != nil {
@@ -196,33 +209,34 @@ func (c *comment) SetModerationStatus(output string) {
err := call.Do()
if err != nil {
utils.PrintJSON(c, nil)
log.Fatalln(errors.Join(errSetModerationStatus, err))
return errors.Join(errSetModerationStatus, err)
}
switch output {
case "json":
utils.PrintJSON(c, nil)
utils.PrintJSON(c, writer)
case "yaml":
utils.PrintYAML(c, nil)
utils.PrintYAML(c, writer)
case "silent":
default:
fmt.Printf(
"Comment moderation status set to %s: %s\n", c.ModerationStatus, c.IDs,
_, _ = fmt.Fprintf(
writer, "Comment moderation status set to %s: %s\n",
c.ModerationStatus, c.IDs,
)
}
return nil
}
func (c *comment) Delete() {
func (c *comment) Delete(writer io.Writer) error {
for _, id := range c.IDs {
call := service.Comments.Delete(id)
err := call.Do()
if err != nil {
utils.PrintJSON(c, nil)
log.Fatalln(errors.Join(errDeleteComment, err))
return errors.Join(errDeleteComment, err)
}
fmt.Printf("Comment %s deleted\n", id)
_, _ = fmt.Fprintf(writer, "Comment %s deleted\n", id)
}
return nil
}
func WithIDs(ids []string) Option {
+28 -21
View File
@@ -6,7 +6,7 @@ import (
"github.com/eat-pray-ai/yutu/pkg/auth"
"github.com/eat-pray-ai/yutu/pkg/utils"
"google.golang.org/api/youtube/v3"
"log"
"io"
)
var (
@@ -30,9 +30,9 @@ type commentThread struct {
}
type CommentThread interface {
get([]string) []*youtube.CommentThread
List([]string, string)
Insert(output string)
Get([]string) ([]*youtube.CommentThread, error)
List([]string, string, io.Writer) error
Insert(output string, writer io.Writer) error
}
type Option func(*commentThread)
@@ -47,7 +47,7 @@ func NewCommentThread(opts ...Option) CommentThread {
return c
}
func (c *commentThread) get(parts []string) []*youtube.CommentThread {
func (c *commentThread) Get(parts []string) ([]*youtube.CommentThread, error) {
call := service.CommentThreads.List(parts)
if len(c.IDs) > 0 {
@@ -89,31 +89,38 @@ func (c *commentThread) get(parts []string) []*youtube.CommentThread {
res, err := call.Do()
if err != nil {
utils.PrintJSON(c, nil)
log.Fatalln(errors.Join(errGetCommentThread, err))
return nil, errors.Join(errGetCommentThread, err)
}
return res.Items
return res.Items, nil
}
func (c *commentThread) List(parts []string, output string) {
commentThreads := c.get(parts)
func (c *commentThread) List(
parts []string, output string, writer io.Writer,
) error {
commentThreads, err := c.Get(parts)
if err != nil {
return err
}
switch output {
case "json":
utils.PrintJSON(commentThreads, nil)
utils.PrintJSON(commentThreads, writer)
case "yaml":
utils.PrintYAML(commentThreads, nil)
utils.PrintYAML(commentThreads, writer)
default:
fmt.Println("ID\tTopLevelCommentID")
_, _ = fmt.Fprintln(writer, "ID\tTopLevelCommentID")
for _, commentThread := range commentThreads {
fmt.Printf(
"%s\t%s\n", commentThread.Id, commentThread.Snippet.TopLevelComment.Id,
_, _ = fmt.Fprintf(
writer, "%s\t%s\n",
commentThread.Id, commentThread.Snippet.TopLevelComment.Id,
)
}
}
return nil
}
func (c *commentThread) Insert(output string) {
func (c *commentThread) Insert(output string, writer io.Writer) error {
ct := &youtube.CommentThread{
Snippet: &youtube.CommentThreadSnippet{
ChannelId: c.ChannelId,
@@ -132,19 +139,19 @@ func (c *commentThread) Insert(output string) {
res, err := service.CommentThreads.Insert([]string{"snippet"}, ct).Do()
if err != nil {
utils.PrintJSON(ct, nil)
log.Fatalln(errors.Join(errInsertCommentThread, err))
return errors.Join(errInsertCommentThread, err)
}
switch output {
case "json":
utils.PrintJSON(res, nil)
utils.PrintJSON(res, writer)
case "yaml":
utils.PrintYAML(res, nil)
utils.PrintYAML(res, writer)
case "silent":
default:
fmt.Printf("CommentThread inserted: %s\n", res.Id)
_, _ = fmt.Fprintf(writer, "CommentThread inserted: %s\n", res.Id)
}
return nil
}
func WithAllThreadsRelatedToChannelId(allThreadsRelatedToChannelId string) Option {
+20 -14
View File
@@ -6,7 +6,7 @@ import (
"github.com/eat-pray-ai/yutu/pkg/auth"
"github.com/eat-pray-ai/yutu/pkg/utils"
"google.golang.org/api/youtube/v3"
"log"
"io"
)
var (
@@ -19,8 +19,8 @@ type i18nLanguage struct {
}
type I18nLanguage interface {
get(parts []string) []*youtube.I18nLanguage
List(parts []string, output string)
Get([]string) ([]*youtube.I18nLanguage, error)
List([]string, string, io.Writer) error
}
type Option func(*i18nLanguage)
@@ -35,7 +35,7 @@ func NewI18nLanguage(opts ...Option) I18nLanguage {
return i
}
func (i *i18nLanguage) get(parts []string) []*youtube.I18nLanguage {
func (i *i18nLanguage) Get(parts []string) ([]*youtube.I18nLanguage, error) {
call := service.I18nLanguages.List(parts)
if i.Hl != "" {
call = call.Hl(i.Hl)
@@ -43,29 +43,35 @@ func (i *i18nLanguage) get(parts []string) []*youtube.I18nLanguage {
res, err := call.Do()
if err != nil {
utils.PrintJSON(i, nil)
log.Fatalln(errors.Join(errGetI18nLanguage, err))
return nil, errors.Join(errGetI18nLanguage, err)
}
return res.Items
return res.Items, nil
}
func (i *i18nLanguage) List(parts []string, output string) {
i18nLanguages := i.get(parts)
func (i *i18nLanguage) List(
parts []string, output string, writer io.Writer,
) error {
i18nLanguages, err := i.Get(parts)
if err != nil {
return err
}
switch output {
case "json":
utils.PrintJSON(i18nLanguages, nil)
utils.PrintJSON(i18nLanguages, writer)
case "yaml":
utils.PrintYAML(i18nLanguages, nil)
utils.PrintYAML(i18nLanguages, writer)
default:
fmt.Println("id\thl\tname")
_, _ = fmt.Fprintln(writer, "id\thl\tname")
for _, i18nLanguage := range i18nLanguages {
fmt.Printf(
"%v\t%v\t%v\n",
_, _ = fmt.Fprintf(
writer, "%v\t%v\t%v\n",
i18nLanguage.Id, i18nLanguage.Snippet.Hl, i18nLanguage.Snippet.Name,
)
}
}
return nil
}
func WithHl(hl string) Option {
+20 -14
View File
@@ -6,7 +6,7 @@ import (
"github.com/eat-pray-ai/yutu/pkg/auth"
"github.com/eat-pray-ai/yutu/pkg/utils"
"google.golang.org/api/youtube/v3"
"log"
"io"
)
var (
@@ -19,8 +19,8 @@ type i18nRegion struct {
}
type I18nRegion interface {
get(parts []string) []*youtube.I18nRegion
List(parts []string, output string)
Get([]string) ([]*youtube.I18nRegion, error)
List([]string, string, io.Writer) error
}
type Option func(*i18nRegion)
@@ -35,7 +35,7 @@ func NewI18nRegion(opts ...Option) I18nRegion {
return i
}
func (i *i18nRegion) get(parts []string) []*youtube.I18nRegion {
func (i *i18nRegion) Get(parts []string) ([]*youtube.I18nRegion, error) {
call := service.I18nRegions.List(parts)
if i.Hl != "" {
call = call.Hl(i.Hl)
@@ -43,29 +43,35 @@ func (i *i18nRegion) get(parts []string) []*youtube.I18nRegion {
res, err := call.Do()
if err != nil {
utils.PrintJSON(i, nil)
log.Fatalln(errors.Join(errGetI18nRegion, err))
return nil, errors.Join(errGetI18nRegion, err)
}
return res.Items
return res.Items, nil
}
func (i *i18nRegion) List(parts []string, output string) {
i18nRegions := i.get(parts)
func (i *i18nRegion) List(
parts []string, output string, writer io.Writer,
) error {
i18nRegions, err := i.Get(parts)
if err != nil {
return err
}
switch output {
case "json":
utils.PrintJSON(i18nRegions, nil)
utils.PrintJSON(i18nRegions, writer)
case "yaml":
utils.PrintYAML(i18nRegions, nil)
utils.PrintYAML(i18nRegions, writer)
default:
fmt.Println("ID\tgl\tname")
_, _ = fmt.Fprintln(writer, "ID\tgl\tname")
for _, i18nRegion := range i18nRegions {
fmt.Printf(
"%v\t%v\t%v\n",
_, _ = fmt.Fprintf(
writer, "%v\t%v\t%v\n",
i18nRegion.Id, i18nRegion.Snippet.Gl, i18nRegion.Snippet.Name,
)
}
}
return nil
}
func WithHl(hl string) Option {
+29
View File
@@ -0,0 +1,29 @@
package pkg
import (
"io"
)
type Lister interface {
List([]string, string, io.Writer) error
}
type Inserter interface {
Insert(string, io.Writer) error
}
type Deleter interface {
Delete(writer io.Writer) error
}
type Updater interface {
Update(string, io.Writer) error
}
type Setter interface {
Set(writer io.Writer) error
}
type Unsetter interface {
Unset(writer io.Writer) error
}
+18 -14
View File
@@ -6,7 +6,7 @@ import (
"github.com/eat-pray-ai/yutu/pkg/auth"
"github.com/eat-pray-ai/yutu/pkg/utils"
"google.golang.org/api/youtube/v3"
"log"
"io"
)
var (
@@ -22,8 +22,8 @@ type member struct {
}
type Member interface {
List([]string, string)
get([]string) []*youtube.Member
List([]string, string, io.Writer) error
Get([]string) ([]*youtube.Member, error)
}
type Option func(*member)
@@ -38,7 +38,7 @@ func NewMember(opts ...Option) Member {
return m
}
func (m *member) get(parts []string) []*youtube.Member {
func (m *member) Get(parts []string) ([]*youtube.Member, error) {
call := service.Members.List(parts)
if m.MemberChannelId != "" {
call = call.FilterByMemberChannelId(m.MemberChannelId)
@@ -56,30 +56,34 @@ func (m *member) get(parts []string) []*youtube.Member {
res, err := call.Do()
if err != nil {
utils.PrintJSON(m, nil)
log.Fatalln(errors.Join(errGetMember, err))
return nil, errors.Join(errGetMember, err)
}
return res.Items
return res.Items, nil
}
func (m *member) List(parts []string, output string) {
members := m.get(parts)
func (m *member) List(parts []string, output string, writer io.Writer) error {
members, err := m.Get(parts)
if err != nil {
return err
}
switch output {
case "json":
utils.PrintJSON(members, nil)
utils.PrintJSON(members, writer)
case "yaml":
utils.PrintYAML(members, nil)
utils.PrintYAML(members, writer)
default:
fmt.Println("channelId\tdisplayName")
_, _ = fmt.Fprintln(writer, "channelId\tdisplayName")
for _, member := range members {
fmt.Printf(
"%s\t%s\n",
_, _ = fmt.Fprintf(
writer, "%s\t%s\n",
member.Snippet.MemberDetails.ChannelId,
member.Snippet.MemberDetails.DisplayName,
)
}
}
return nil
}
func WithMemberChannelId(channelId string) Option {
+22 -14
View File
@@ -6,7 +6,7 @@ import (
"github.com/eat-pray-ai/yutu/pkg/auth"
"github.com/eat-pray-ai/yutu/pkg/utils"
"google.golang.org/api/youtube/v3"
"log"
"io"
)
var (
@@ -17,8 +17,8 @@ var (
type membershipsLevel struct{}
type MembershipsLevel interface {
List([]string, string)
get([]string) []*youtube.MembershipsLevel
List([]string, string, io.Writer) error
Get([]string) ([]*youtube.MembershipsLevel, error)
}
type Option func(*membershipsLevel)
@@ -33,33 +33,41 @@ func NewMembershipsLevel(opts ...Option) MembershipsLevel {
return m
}
func (m *membershipsLevel) get(parts []string) []*youtube.MembershipsLevel {
func (m *membershipsLevel) Get(parts []string) (
[]*youtube.MembershipsLevel, error,
) {
call := service.MembershipsLevels.List(parts)
res, err := call.Do()
if err != nil {
utils.PrintJSON(m, nil)
log.Fatalln(errors.Join(errGetMembershipsLevel, err))
return nil, errors.Join(errGetMembershipsLevel, err)
}
return res.Items
return res.Items, nil
}
func (m *membershipsLevel) List(parts []string, output string) {
membershipsLevels := m.get(parts)
func (m *membershipsLevel) List(
parts []string, output string, writer io.Writer,
) error {
membershipsLevels, err := m.Get(parts)
if err != nil {
return err
}
switch output {
case "json":
utils.PrintJSON(membershipsLevels, nil)
utils.PrintJSON(membershipsLevels, writer)
case "yaml":
utils.PrintYAML(membershipsLevels, nil)
utils.PrintYAML(membershipsLevels, writer)
default:
fmt.Println("id\tdisplayName")
_, _ = fmt.Fprintln(writer, "id\tdisplayName")
for _, membershipsLevel := range membershipsLevels {
fmt.Printf(
"%v\t%v\n", membershipsLevel.Id,
_, _ = fmt.Fprintf(
writer, "%v\t%v\n", membershipsLevel.Id,
membershipsLevel.Snippet.LevelDetails.DisplayName,
)
}
}
return nil
}
func WithService(svc *youtube.Service) Option {
+45 -34
View File
@@ -5,9 +5,8 @@ import (
"fmt"
"github.com/eat-pray-ai/yutu/pkg/auth"
"github.com/eat-pray-ai/yutu/pkg/utils"
"log"
"google.golang.org/api/youtube/v3"
"io"
)
var (
@@ -35,11 +34,11 @@ type playlist struct {
}
type Playlist interface {
List([]string, string)
Insert(output string)
Update(output string)
Delete()
get([]string) []*youtube.Playlist
List([]string, string, io.Writer) error
Insert(string, io.Writer) error
Update(string, io.Writer) error
Delete(io.Writer) error
Get([]string) ([]*youtube.Playlist, error)
}
type Option func(*playlist)
@@ -54,7 +53,7 @@ func NewPlaylist(opts ...Option) Playlist {
return p
}
func (p *playlist) get(parts []string) []*youtube.Playlist {
func (p *playlist) Get(parts []string) ([]*youtube.Playlist, error) {
call := service.Playlists.List(parts)
if len(p.IDs) > 0 {
@@ -79,29 +78,33 @@ func (p *playlist) get(parts []string) []*youtube.Playlist {
res, err := call.Do()
if err != nil {
utils.PrintJSON(p, nil)
log.Fatalln(errors.Join(errGetPlaylist, err))
return nil, errors.Join(errGetPlaylist, err)
}
return res.Items
return res.Items, nil
}
func (p *playlist) List(parts []string, output string) {
playlists := p.get(parts)
func (p *playlist) List(parts []string, output string, writer io.Writer) error {
playlists, err := p.Get(parts)
if err != nil {
return err
}
switch output {
case "json":
utils.PrintJSON(playlists, nil)
utils.PrintJSON(playlists, writer)
case "yaml":
utils.PrintYAML(playlists, nil)
utils.PrintYAML(playlists, writer)
default:
fmt.Println("ID\tTitle")
_, _ = fmt.Fprintln(writer, "ID\tTitle")
for _, playlist := range playlists {
fmt.Printf("%s\t%s\n", playlist.Id, playlist.Snippet.Title)
_, _ = fmt.Fprintf(writer, "%s\t%s\n", playlist.Id, playlist.Snippet.Title)
}
}
return nil
}
func (p *playlist) Insert(output string) {
func (p *playlist) Insert(output string, writer io.Writer) error {
upload := &youtube.Playlist{
Snippet: &youtube.PlaylistSnippet{
Title: p.Title,
@@ -118,23 +121,31 @@ func (p *playlist) Insert(output string) {
call := service.Playlists.Insert([]string{"snippet", "status"}, upload)
res, err := call.Do()
if err != nil {
utils.PrintJSON(p, nil)
log.Fatalln(errors.Join(errInsertPlaylist, err))
return errors.Join(errInsertPlaylist, err)
}
switch output {
case "json":
utils.PrintJSON(res, nil)
utils.PrintJSON(res, writer)
case "yaml":
utils.PrintYAML(res, nil)
utils.PrintYAML(res, writer)
case "silent":
default:
fmt.Printf("Playlist inserted: %s\n", res.Id)
_, _ = fmt.Fprintf(writer, "Playlist inserted: %s\n", res.Id)
}
return nil
}
func (p *playlist) Update(output string) {
playlist := p.get([]string{"id", "snippet", "status"})[0]
func (p *playlist) Update(output string, writer io.Writer) error {
playlists, err := p.Get([]string{"id", "snippet", "status"})
if err != nil {
return errors.Join(errUpdatePlaylist, err)
}
if len(playlists) == 0 {
return errGetPlaylist
}
playlist := playlists[0]
if p.Title != "" {
playlist.Snippet.Title = p.Title
}
@@ -154,22 +165,22 @@ func (p *playlist) Update(output string) {
call := service.Playlists.Update([]string{"snippet", "status"}, playlist)
res, err := call.Do()
if err != nil {
utils.PrintJSON(p, nil)
log.Fatalln(errors.Join(errUpdatePlaylist, err))
return errors.Join(errUpdatePlaylist, err)
}
switch output {
case "json":
utils.PrintJSON(res, nil)
utils.PrintJSON(res, writer)
case "yaml":
utils.PrintYAML(res, nil)
utils.PrintYAML(res, writer)
case "silent":
default:
fmt.Printf("Playlist updated: %s\n", res.Id)
_, _ = fmt.Fprintf(writer, "Playlist updated: %s\n", res.Id)
}
return nil
}
func (p *playlist) Delete() {
func (p *playlist) Delete(writer io.Writer) error {
for _, id := range p.IDs {
call := service.Playlists.Delete(id)
if p.OnBehalfOfContentOwner != "" {
@@ -178,11 +189,11 @@ func (p *playlist) Delete() {
err := call.Do()
if err != nil {
utils.PrintJSON(p, nil)
log.Fatalln(errors.Join(errDeletePlaylist, err))
return errors.Join(errDeletePlaylist, err)
}
fmt.Printf("Playlist %s deleted", id)
_, _ = fmt.Fprintf(writer, "Playlist %s deleted", id)
}
return nil
}
func WithIDs(ids []string) Option {
+50 -37
View File
@@ -6,7 +6,7 @@ import (
"github.com/eat-pray-ai/yutu/pkg/auth"
"github.com/eat-pray-ai/yutu/pkg/utils"
"google.golang.org/api/youtube/v3"
"log"
"io"
"os"
)
@@ -34,11 +34,11 @@ type playlistImage struct {
}
type PlaylistImage interface {
get([]string) []*youtube.PlaylistImage
List([]string, string)
Insert(string)
Update(string)
Delete()
Get([]string) ([]*youtube.PlaylistImage, error)
List([]string, string, io.Writer) error
Insert(string, io.Writer) error
Update(string, io.Writer) error
Delete(io.Writer) error
}
type Option func(*playlistImage)
@@ -51,7 +51,7 @@ func NewPlaylistImage(opts ...Option) PlaylistImage {
return pi
}
func (pi *playlistImage) get(parts []string) []*youtube.PlaylistImage {
func (pi *playlistImage) Get(parts []string) ([]*youtube.PlaylistImage, error) {
call := service.PlaylistImages.List()
call = call.Part(parts...)
@@ -71,36 +71,42 @@ func (pi *playlistImage) get(parts []string) []*youtube.PlaylistImage {
res, err := call.Do()
if err != nil {
utils.PrintJSON(pi, nil)
log.Fatalln(errors.Join(errGetPlaylistImage, err))
return nil, errors.Join(errGetPlaylistImage, err)
}
return res.Items
return res.Items, nil
}
func (pi *playlistImage) List(parts []string, output string) {
playlistImages := pi.get(parts)
func (pi *playlistImage) List(
parts []string, output string, writer io.Writer,
) error {
playlistImages, err := pi.Get(parts)
if err != nil {
return err
}
switch output {
case "json":
utils.PrintJSON(playlistImages, nil)
utils.PrintJSON(playlistImages, writer)
case "yaml":
utils.PrintYAML(playlistImages, nil)
utils.PrintYAML(playlistImages, writer)
default:
fmt.Println("ID\tKind\tPlaylistID\tType")
_, _ = fmt.Fprintln(writer, "ID\tKind\tPlaylistID\tType")
for _, image := range playlistImages {
fmt.Printf(
_, _ = fmt.Fprintf(
writer,
"%s\t%s\t%s\t%s\n",
image.Id, image.Kind, image.Snippet.PlaylistId, image.Snippet.Type,
)
}
}
return nil
}
func (pi *playlistImage) Insert(output string) {
func (pi *playlistImage) Insert(output string, writer io.Writer) error {
file, err := os.Open(pi.File)
if err != nil {
utils.PrintJSON(pi, nil)
log.Fatalln(errors.Join(errInsertPlaylistImage, err))
return errors.Join(errInsertPlaylistImage, err)
}
defer file.Close()
@@ -125,23 +131,31 @@ func (pi *playlistImage) Insert(output string) {
call = call.Part("kind", "snippet")
res, err := call.Do()
if err != nil {
utils.PrintJSON(pi, nil)
log.Fatalln(errors.Join(errInsertPlaylistImage, err))
return errors.Join(errInsertPlaylistImage, err)
}
switch output {
case "json":
utils.PrintJSON(res, nil)
utils.PrintJSON(res, writer)
case "yaml":
utils.PrintYAML(res, nil)
utils.PrintYAML(res, writer)
case "silent":
default:
fmt.Printf("PlaylistImage inserted: %s\n", res.Id)
_, _ = fmt.Fprintf(writer, "PlaylistImage inserted: %s\n", res.Id)
}
return nil
}
func (pi *playlistImage) Update(output string) {
playlistImage := pi.get([]string{"id", "kind", "snippet"})[0]
func (pi *playlistImage) Update(output string, writer io.Writer) error {
playlistImages, err := pi.Get([]string{"id", "kind", "snippet"})
if err != nil {
return errors.Join(errUpdatePlaylistImage, err)
}
if len(playlistImages) == 0 {
return errGetPlaylistImage
}
playlistImage := playlistImages[0]
if pi.PlaylistID != "" {
playlistImage.Snippet.PlaylistId = pi.PlaylistID
}
@@ -162,8 +176,7 @@ func (pi *playlistImage) Update(output string) {
if pi.File != "" {
file, err := os.Open(pi.File)
if err != nil {
utils.PrintJSON(pi, nil)
log.Fatalln(errors.Join(errUpdatePlaylistImage, err))
return errors.Join(errUpdatePlaylistImage, err)
}
defer file.Close()
call = call.Media(file)
@@ -172,22 +185,22 @@ func (pi *playlistImage) Update(output string) {
res, err := call.Do()
if err != nil {
utils.PrintJSON(pi, nil)
log.Fatalln(errors.Join(errUpdatePlaylistImage, err))
return errors.Join(errUpdatePlaylistImage, err)
}
switch output {
case "json":
utils.PrintJSON(res, nil)
utils.PrintJSON(res, writer)
case "yaml":
utils.PrintYAML(res, nil)
utils.PrintYAML(res, writer)
case "silent":
default:
fmt.Printf("PlaylistImage updated: %s\n", res.Id)
_, _ = fmt.Fprintf(writer, "PlaylistImage updated: %s\n", res.Id)
}
return nil
}
func (pi *playlistImage) Delete() {
func (pi *playlistImage) Delete(writer io.Writer) error {
for _, id := range pi.IDs {
call := service.PlaylistImages.Delete()
call = call.Id(id)
@@ -197,11 +210,11 @@ func (pi *playlistImage) Delete() {
err := call.Do()
if err != nil {
utils.PrintJSON(pi, nil)
log.Fatalln(errors.Join(errDeletePlaylistImage, err))
return errors.Join(errDeletePlaylistImage, err)
}
fmt.Printf("PlaylistImage %s deleted\n", id)
_, _ = fmt.Fprintf(writer, "PlaylistImage %s deleted\n", id)
}
return nil
}
func WithIDs(ids []string) Option {
+50 -34
View File
@@ -4,10 +4,9 @@ import (
"errors"
"fmt"
"github.com/eat-pray-ai/yutu/pkg/auth"
"log"
"github.com/eat-pray-ai/yutu/pkg/utils"
"google.golang.org/api/youtube/v3"
"io"
)
var (
@@ -36,11 +35,11 @@ type playlistItem struct {
}
type PlaylistItem interface {
List([]string, string)
Insert(output string)
Update(output string)
Delete()
get([]string) []*youtube.PlaylistItem
List([]string, string, io.Writer) error
Insert(string, io.Writer) error
Update(string, io.Writer) error
Delete(io.Writer) error
Get([]string) ([]*youtube.PlaylistItem, error)
}
type Option func(*playlistItem)
@@ -55,7 +54,7 @@ func NewPlaylistItem(opts ...Option) PlaylistItem {
return p
}
func (pi *playlistItem) get(parts []string) []*youtube.PlaylistItem {
func (pi *playlistItem) Get(parts []string) ([]*youtube.PlaylistItem, error) {
call := service.PlaylistItems.List(parts)
if len(pi.IDs) > 0 {
call = call.Id(pi.IDs...)
@@ -75,29 +74,38 @@ func (pi *playlistItem) get(parts []string) []*youtube.PlaylistItem {
call = call.MaxResults(pi.MaxResults)
res, err := call.Do()
if err != nil {
utils.PrintJSON(pi, nil)
log.Fatalln(errors.Join(errGetPlaylistItem, err))
return nil, errors.Join(errGetPlaylistItem, err)
}
return res.Items
return res.Items, nil
}
func (pi *playlistItem) List(parts []string, output string) {
playlistItems := pi.get(parts)
func (pi *playlistItem) List(
parts []string, output string, writer io.Writer,
) error {
playlistItems, err := pi.Get(parts)
if err != nil {
return err
}
switch output {
case "json":
utils.PrintJSON(playlistItems, nil)
utils.PrintJSON(playlistItems, writer)
case "yaml":
utils.PrintYAML(playlistItems, nil)
utils.PrintYAML(playlistItems, writer)
default:
fmt.Println("ID\tTitle")
_, _ = fmt.Fprintln(writer, "ID\tTitle")
for _, playlistItem := range playlistItems {
fmt.Printf("%s\t%s\n", playlistItem.Id, playlistItem.Snippet.Title)
_, _ = fmt.Fprintf(
writer, "%s\t%s\n",
playlistItem.Id, playlistItem.Snippet.Title,
)
}
}
return nil
}
func (pi *playlistItem) Insert(output string) {
func (pi *playlistItem) Insert(output string, writer io.Writer) error {
var resourceId *youtube.ResourceId
switch pi.Kind {
case "video":
@@ -139,23 +147,31 @@ func (pi *playlistItem) Insert(output string) {
res, err := call.Do()
if err != nil {
utils.PrintJSON(pi, nil)
log.Fatalln(errors.Join(errInsertPlaylistItem, err))
return errors.Join(errInsertPlaylistItem, err)
}
switch output {
case "json":
utils.PrintJSON(res, nil)
utils.PrintJSON(res, writer)
case "yaml":
utils.PrintYAML(res, nil)
utils.PrintYAML(res, writer)
case "silent":
default:
fmt.Printf("Playlist Item inserted: %s\n", res.Id)
_, _ = fmt.Fprintf(writer, "Playlist Item inserted: %s\n", res.Id)
}
return nil
}
func (pi *playlistItem) Update(output string) {
playlistItem := pi.get([]string{"id", "snippet", "status"})[0]
func (pi *playlistItem) Update(output string, writer io.Writer) error {
playlistItems, err := pi.Get([]string{"id", "snippet", "status"})
if err != nil {
return errors.Join(errUpdatePlaylistItem, err)
}
if len(playlistItems) == 0 {
return errGetPlaylistItem
}
playlistItem := playlistItems[0]
if pi.Title != "" {
playlistItem.Snippet.Title = pi.Title
}
@@ -175,22 +191,22 @@ func (pi *playlistItem) Update(output string) {
res, err := call.Do()
if err != nil {
utils.PrintJSON(pi, nil)
log.Fatalln(errors.Join(errUpdatePlaylistItem, err))
return errors.Join(errUpdatePlaylistItem, err)
}
switch output {
case "json":
utils.PrintJSON(res, nil)
utils.PrintJSON(res, writer)
case "yaml":
utils.PrintYAML(res, nil)
utils.PrintYAML(res, writer)
case "silent":
default:
fmt.Printf("Playlist Item updated: %s\n", res.Id)
_, _ = fmt.Fprintf(writer, "Playlist Item updated: %s\n", res.Id)
}
return nil
}
func (pi *playlistItem) Delete() {
func (pi *playlistItem) Delete(writer io.Writer) error {
for _, id := range pi.IDs {
call := service.PlaylistItems.Delete(id)
if pi.OnBehalfOfContentOwner != "" {
@@ -199,12 +215,12 @@ func (pi *playlistItem) Delete() {
err := call.Do()
if err != nil {
utils.PrintJSON(pi, nil)
log.Fatalln(errors.Join(errDeletePlaylistItem, err))
return errors.Join(errDeletePlaylistItem, err)
}
fmt.Printf("Playlsit Item %s deleted", id)
_, _ = fmt.Fprintf(writer, "Playlsit Item %s deleted", id)
}
return nil
}
func WithIDs(ids []string) Option {
+19 -13
View File
@@ -6,7 +6,7 @@ import (
"github.com/eat-pray-ai/yutu/pkg/auth"
"github.com/eat-pray-ai/yutu/pkg/utils"
"google.golang.org/api/youtube/v3"
"log"
"io"
)
var (
@@ -47,8 +47,8 @@ type search struct {
}
type Search interface {
get([]string) []*youtube.SearchResult
List([]string, string)
Get([]string) ([]*youtube.SearchResult, error)
List([]string, string, io.Writer) error
}
type Option func(*search)
@@ -63,7 +63,7 @@ func NewSearch(opts ...Option) Search {
return s
}
func (s *search) get(parts []string) []*youtube.SearchResult {
func (s *search) Get(parts []string) ([]*youtube.SearchResult, error) {
call := service.Search.List(parts)
if s.ChannelId != "" {
call.ChannelId(s.ChannelId)
@@ -184,26 +184,32 @@ func (s *search) get(parts []string) []*youtube.SearchResult {
res, err := call.Do()
if err != nil {
utils.PrintJSON(s, nil)
log.Fatalln(errors.Join(errGetSearch, err))
return nil, errors.Join(errGetSearch, err)
}
return res.Items
return res.Items, nil
}
func (s *search) List(parts []string, output string) {
results := s.get(parts)
func (s *search) List(parts []string, output string, writer io.Writer) error {
results, err := s.Get(parts)
if err != nil {
return err
}
switch output {
case "json":
utils.PrintJSON(results, nil)
utils.PrintJSON(results, writer)
case "yaml":
utils.PrintYAML(results, nil)
utils.PrintYAML(results, writer)
default:
fmt.Println("Kind\tTitle")
_, _ = fmt.Fprintln(writer, "Kind\tTitle")
for _, result := range results {
fmt.Printf("%v\t%v\n", result.Id.Kind, result.Snippet.Title)
_, _ = fmt.Fprintf(
writer, "%v\t%v\n", result.Id.Kind, result.Snippet.Title,
)
}
}
return nil
}
func WithChannelId(channelId string) Option {
+32 -26
View File
@@ -6,7 +6,7 @@ import (
"github.com/eat-pray-ai/yutu/pkg/auth"
"github.com/eat-pray-ai/yutu/pkg/utils"
"google.golang.org/api/youtube/v3"
"log"
"io"
)
var (
@@ -33,10 +33,10 @@ type subscription struct {
}
type Subscription interface {
get([]string) []*youtube.Subscription
List([]string, string)
Insert(output string)
Delete()
Get([]string) ([]*youtube.Subscription, error)
List([]string, string, io.Writer) error
Insert(string, io.Writer) error
Delete(io.Writer) error
}
type Option func(*subscription)
@@ -51,7 +51,7 @@ func NewSubscription(opts ...Option) Subscription {
return s
}
func (s *subscription) get(parts []string) []*youtube.Subscription {
func (s *subscription) Get(parts []string) ([]*youtube.Subscription, error) {
call := service.Subscriptions.List(parts)
if len(s.IDs) > 0 {
call = call.Id(s.IDs...)
@@ -89,32 +89,38 @@ func (s *subscription) get(parts []string) []*youtube.Subscription {
res, err := call.Do()
if err != nil {
utils.PrintJSON(s, nil)
log.Fatalln(errors.Join(errGetSubscription, err))
return nil, errors.Join(errGetSubscription, err)
}
return res.Items
return res.Items, nil
}
func (s *subscription) List(parts []string, output string) {
subscriptions := s.get(parts)
func (s *subscription) List(
parts []string, output string, writer io.Writer,
) error {
subscriptions, err := s.Get(parts)
if err != nil {
return errors.Join(errGetSubscription, err)
}
switch output {
case "json":
utils.PrintJSON(subscriptions, nil)
utils.PrintJSON(subscriptions, writer)
case "yaml":
utils.PrintYAML(subscriptions, nil)
utils.PrintYAML(subscriptions, writer)
default:
fmt.Println("ID\tChannel ID\tChannel Title")
_, _ = fmt.Fprintln(writer, "ID\tChannel ID\tChannel Title")
for _, subscription := range subscriptions {
fmt.Printf(
"%s\t%s\t%s\n", subscription.Id,
_, _ = fmt.Fprintf(
writer, "%s\t%s\t%s\n", subscription.Id,
subscription.Snippet.ResourceId.ChannelId, subscription.Snippet.Title,
)
}
}
return nil
}
func (s *subscription) Insert(output string) {
func (s *subscription) Insert(output string, writer io.Writer) error {
subscription := &youtube.Subscription{
Snippet: &youtube.SubscriptionSnippet{
ChannelId: s.SubscriberChannelId,
@@ -129,31 +135,31 @@ func (s *subscription) Insert(output string) {
call := service.Subscriptions.Insert([]string{"snippet"}, subscription)
res, err := call.Do()
if err != nil {
utils.PrintJSON(s, nil)
log.Fatalln(errors.Join(errInsertSubscription, err))
return errors.Join(errInsertSubscription, err)
}
switch output {
case "json":
utils.PrintJSON(res, nil)
utils.PrintJSON(res, writer)
case "yaml":
utils.PrintYAML(res, nil)
utils.PrintYAML(res, writer)
default:
fmt.Printf("Subscription inserted: %s\n", res.Id)
_, _ = fmt.Fprintf(writer, "Subscription inserted: %s\n", res.Id)
}
return nil
}
func (s *subscription) Delete() {
func (s *subscription) Delete(writer io.Writer) error {
for _, id := range s.IDs {
call := service.Subscriptions.Delete(id)
err := call.Do()
if err != nil {
utils.PrintJSON(s, nil)
log.Fatalln(errors.Join(errDeleteSubscription, err))
return errors.Join(errDeleteSubscription, err)
}
fmt.Printf("Subscription %s deleted", id)
_, _ = fmt.Fprintf(writer, "Subscription %s deleted", id)
}
return nil
}
func WithIDs(ids []string) Option {
+21 -13
View File
@@ -6,7 +6,7 @@ import (
"github.com/eat-pray-ai/yutu/pkg/auth"
"github.com/eat-pray-ai/yutu/pkg/utils"
"google.golang.org/api/youtube/v3"
"log"
"io"
)
var (
@@ -20,8 +20,8 @@ type superChatEvent struct {
}
type SuperChatEvent interface {
get([]string) []*youtube.SuperChatEvent
List([]string, string)
Get([]string) ([]*youtube.SuperChatEvent, error)
List([]string, string, io.Writer) error
}
type Option func(*superChatEvent)
@@ -36,7 +36,7 @@ func NewSuperChatEvent(opts ...Option) SuperChatEvent {
return s
}
func (s *superChatEvent) get(parts []string) []*youtube.SuperChatEvent {
func (s *superChatEvent) Get(parts []string) ([]*youtube.SuperChatEvent, error) {
call := service.SuperChatEvents.List(parts)
if s.Hl != "" {
call = call.Hl(s.Hl)
@@ -48,26 +48,34 @@ func (s *superChatEvent) get(parts []string) []*youtube.SuperChatEvent {
res, err := call.Do()
if err != nil {
utils.PrintJSON(s, nil)
log.Fatalln(errors.Join(errGetSuperChatEvent, err))
return nil, errors.Join(errGetSuperChatEvent, err)
}
return res.Items
return res.Items, nil
}
func (s *superChatEvent) List(parts []string, output string) {
events := s.get(parts)
func (s *superChatEvent) List(
parts []string, output string, writer io.Writer,
) error {
events, err := s.Get(parts)
if err != nil {
return errors.Join(errGetSuperChatEvent, err)
}
switch output {
case "json":
utils.PrintJSON(events, nil)
utils.PrintJSON(events, writer)
case "yaml":
utils.PrintYAML(events, nil)
utils.PrintYAML(events, writer)
default:
fmt.Println("ID\tAmount")
_, _ = fmt.Fprintln(writer, "ID\tAmount")
for _, event := range events {
fmt.Printf("%v\t%v\n", event.Id, event.Snippet.AmountMicros)
_, _ = fmt.Fprintf(
writer, "%v\t%v\n", event.Id, event.Snippet.AmountMicros,
)
}
}
return nil
}
func WithHl(hl string) Option {
+10 -10
View File
@@ -6,7 +6,7 @@ import (
"github.com/eat-pray-ai/yutu/pkg/auth"
"github.com/eat-pray-ai/yutu/pkg/utils"
"google.golang.org/api/youtube/v3"
"log"
"io"
"os"
)
@@ -21,7 +21,7 @@ type thumbnail struct {
}
type Thumbnail interface {
Set(output string)
Set(string, io.Writer) error
}
type Option func(*thumbnail)
@@ -34,28 +34,28 @@ func NewThumbnail(opts ...Option) Thumbnail {
return t
}
func (t *thumbnail) Set(output string) {
func (t *thumbnail) Set(output string, writer io.Writer) error {
file, err := os.Open(t.File)
if err != nil {
utils.PrintJSON(t, nil)
log.Fatalln(errors.Join(errSetThumbnail, err))
return errors.Join(errSetThumbnail, err)
}
call := service.Thumbnails.Set(t.VideoId).Media(file)
res, err := call.Do()
if err != nil {
utils.PrintJSON(t, nil)
log.Fatalln(errors.Join(errSetThumbnail, err))
return errors.Join(errSetThumbnail, err)
}
switch output {
case "json":
utils.PrintJSON(res, nil)
utils.PrintJSON(res, writer)
case "yaml":
utils.PrintYAML(res, nil)
utils.PrintYAML(res, writer)
case "silent":
default:
fmt.Println("Thumbnail set done")
_, _ = fmt.Fprintf(writer, "Thumbnail set for video %s", t.VideoId)
}
return nil
}
func WithVideoId(videoId string) Option {
+70 -57
View File
@@ -6,7 +6,7 @@ import (
"github.com/eat-pray-ai/yutu/pkg/auth"
"github.com/eat-pray-ai/yutu/pkg/playlistItem"
"github.com/eat-pray-ai/yutu/pkg/thumbnail"
"log"
"io"
"os"
"slices"
@@ -62,14 +62,14 @@ type video struct {
}
type Video interface {
List([]string, string)
Insert(string)
Update(string)
Rate()
GetRating(string)
Delete()
ReportAbuse()
get([]string) []*youtube.Video
List([]string, string, io.Writer) error
Insert(string, io.Writer) error
Update(string, io.Writer) error
Rate(io.Writer) error
GetRating(string, io.Writer) error
Delete(io.Writer) error
ReportAbuse(io.Writer) error
Get([]string) ([]*youtube.Video, error)
}
type Option func(*video)
@@ -84,7 +84,7 @@ func NewVideo(opts ...Option) Video {
return v
}
func (v *video) get(parts []string) []*youtube.Video {
func (v *video) Get(parts []string) ([]*youtube.Video, error) {
call := service.Videos.List(parts)
if len(v.IDs) > 0 {
call = call.Id(v.IDs...)
@@ -124,33 +124,36 @@ func (v *video) get(parts []string) []*youtube.Video {
res, err := call.Do()
if err != nil {
utils.PrintJSON(v, nil)
log.Fatalln(errors.Join(errGetVideo, err))
return nil, errors.Join(errGetVideo, err)
}
return res.Items
return res.Items, nil
}
func (v *video) List(parts []string, output string) {
videos := v.get(parts)
func (v *video) List(parts []string, output string, writer io.Writer) error {
videos, err := v.Get(parts)
if err != nil {
return err
}
switch output {
case "json":
utils.PrintJSON(videos, nil)
utils.PrintJSON(videos, writer)
case "yaml":
utils.PrintYAML(videos, nil)
utils.PrintYAML(videos, writer)
default:
fmt.Println("ID\tTitle")
_, _ = fmt.Fprintln(writer, "ID\tTitle")
for _, video := range videos {
fmt.Printf("%s\t%s\n", video.Id, video.Snippet.Title)
_, _ = fmt.Fprintf(writer, "%s\t%s\n", video.Id, video.Snippet.Title)
}
}
return nil
}
func (v *video) Insert(output string) {
func (v *video) Insert(output string, writer io.Writer) error {
file, err := os.Open(v.File)
if err != nil {
utils.PrintJSON(v, nil)
log.Fatalln(errors.Join(errInsertVideo, err))
return errors.Join(errInsertVideo, err)
}
defer file.Close()
@@ -210,8 +213,7 @@ func (v *video) Insert(output string) {
res, err := call.Media(file).Do()
if err != nil {
utils.PrintJSON(v, nil)
log.Fatalln(errors.Join(errInsertVideo, err))
return errors.Join(errInsertVideo, err)
}
if v.Thumbnail != "" {
@@ -220,7 +222,7 @@ func (v *video) Insert(output string) {
thumbnail.WithFile(v.Thumbnail),
thumbnail.WithService(service),
)
t.Set("silent")
t.Set("silent", nil)
}
if v.PlaylistId != "" {
@@ -234,22 +236,32 @@ func (v *video) Insert(output string) {
playlistItem.WithPrivacy(res.Status.PrivacyStatus),
playlistItem.WithService(service),
)
pi.Insert("silent")
_ = pi.Insert("silent", writer)
}
switch output {
case "json":
utils.PrintJSON(res, nil)
utils.PrintJSON(res, writer)
case "yaml":
utils.PrintYAML(res, nil)
utils.PrintYAML(res, writer)
case "silent":
default:
fmt.Printf("Video inserted: %s\n", res.Id)
_, _ = fmt.Fprintf(writer, "Video inserted: %s\n", res.Id)
}
return nil
}
func (v *video) Update(output string) {
video := v.get([]string{"id", "snippet", "status"})[0]
func (v *video) Update(output string, writer io.Writer) error {
videos, err := v.Get([]string{"id", "snippet", "status"})
if err != nil {
return errors.Join(errUpdateVideo, err)
}
if len(videos) == 0 {
return errGetVideo
}
video := videos[0]
if v.Title != "" {
video.Snippet.Title = v.Title
}
@@ -286,8 +298,7 @@ func (v *video) Update(output string) {
res, err := call.Do()
if err != nil {
utils.PrintJSON(v, nil)
log.Fatalln(errors.Join(errUpdateVideo, err))
return errors.Join(errUpdateVideo, err)
}
if v.Thumbnail != "" {
@@ -296,7 +307,7 @@ func (v *video) Update(output string) {
thumbnail.WithFile(v.Thumbnail),
thumbnail.WithService(service),
)
t.Set("silent")
t.Set("silent", nil)
}
if v.PlaylistId != "" {
@@ -310,57 +321,59 @@ func (v *video) Update(output string) {
playlistItem.WithPrivacy(res.Status.PrivacyStatus),
playlistItem.WithService(service),
)
pi.Insert("silent")
_ = pi.Insert("silent", writer)
}
switch output {
case "json":
utils.PrintJSON(res, nil)
utils.PrintJSON(res, writer)
case "yaml":
utils.PrintYAML(res, nil)
utils.PrintYAML(res, writer)
case "silent":
default:
fmt.Printf("Video updated: %s\n", res.Id)
_, _ = fmt.Fprintf(writer, "Video updated: %s\n", res.Id)
}
return nil
}
func (v *video) Rate() {
func (v *video) Rate(writer io.Writer) error {
for _, id := range v.IDs {
call := service.Videos.Rate(id, v.Rating)
err := call.Do()
if err != nil {
utils.PrintJSON(v, nil)
log.Fatalln(errors.Join(errRating, err))
return errors.Join(errRating, err)
}
fmt.Printf("Video %s rated %s\n", id, v.Rating)
_, _ = fmt.Fprintf(writer, "Video %s rated %s\n", id, v.Rating)
}
return nil
}
func (v *video) GetRating(output string) {
func (v *video) GetRating(output string, writer io.Writer) error {
call := service.Videos.GetRating(v.IDs)
if v.OnBehalfOfContentOwner != "" {
call = call.OnBehalfOfContentOwner(v.OnBehalfOfContentOwnerChannel)
}
res, err := call.Do()
if err != nil {
utils.PrintJSON(v, nil)
log.Fatalln(errors.Join(errGetRating, err))
return errors.Join(errGetRating, err)
}
switch output {
case "json":
utils.PrintJSON(res.Items, nil)
utils.PrintJSON(res.Items, writer)
case "yaml":
utils.PrintYAML(res.Items, nil)
utils.PrintYAML(res.Items, writer)
default:
fmt.Println("ID\tRating")
_, _ = fmt.Fprintln(writer, "ID\tRating")
for _, item := range res.Items {
fmt.Printf("%s\t%s\n", item.VideoId, item.Rating)
_, _ = fmt.Fprintf(writer, "%s\t%s\n", item.VideoId, item.Rating)
}
}
return nil
}
func (v *video) Delete() {
func (v *video) Delete(writer io.Writer) error {
for _, id := range v.IDs {
call := service.Videos.Delete(id)
if v.OnBehalfOfContentOwner != "" {
@@ -369,14 +382,14 @@ func (v *video) Delete() {
err := call.Do()
if err != nil {
utils.PrintJSON(v, nil)
log.Fatalln(errors.Join(errDeleteVideo, err))
return errors.Join(errDeleteVideo, err)
}
fmt.Printf("Video %s deleted", id)
_, _ = fmt.Fprintf(writer, "Video %s deleted", id)
}
return nil
}
func (v *video) ReportAbuse() {
func (v *video) ReportAbuse(writer io.Writer) error {
for _, id := range v.IDs {
videoAbuseReport := &youtube.VideoAbuseReport{
Comments: v.Comments,
@@ -393,12 +406,12 @@ func (v *video) ReportAbuse() {
err := call.Do()
if err != nil {
utils.PrintJSON(v, nil)
log.Fatalln(errors.Join(errReportAbuse, err))
return errors.Join(errReportAbuse, err)
}
fmt.Printf("Video %s reported for abuse", id)
_, _ = fmt.Fprintf(writer, "Video %s reported for abuse", id)
}
return nil
}
func WithIDs(ids []string) Option {
@@ -6,7 +6,7 @@ import (
"github.com/eat-pray-ai/yutu/pkg/auth"
"github.com/eat-pray-ai/yutu/pkg/utils"
"google.golang.org/api/youtube/v3"
"log"
"io"
)
var (
@@ -19,8 +19,8 @@ type videoAbuseReportReason struct {
}
type VideoAbuseReportReason interface {
get([]string) []*youtube.VideoAbuseReportReason
List([]string, string)
Get([]string) ([]*youtube.VideoAbuseReportReason, error)
List([]string, string, io.Writer) error
}
type Option func(*videoAbuseReportReason)
@@ -33,7 +33,9 @@ func NewVideoAbuseReportReason(opt ...Option) VideoAbuseReportReason {
return va
}
func (va *videoAbuseReportReason) get(parts []string) []*youtube.VideoAbuseReportReason {
func (va *videoAbuseReportReason) Get(parts []string) (
[]*youtube.VideoAbuseReportReason, error,
) {
call := service.VideoAbuseReportReasons.List(parts)
if va.Hl != "" {
call = call.Hl(va.Hl)
@@ -41,29 +43,35 @@ func (va *videoAbuseReportReason) get(parts []string) []*youtube.VideoAbuseRepor
res, err := call.Do()
if err != nil {
utils.PrintJSON(va, nil)
log.Fatalln(errors.Join(errGetVideoAbuseReportReason, err))
return nil, errors.Join(errGetVideoAbuseReportReason, err)
}
return res.Items
return res.Items, nil
}
func (va *videoAbuseReportReason) List(parts []string, output string) {
videoAbuseReportReasons := va.get(parts)
func (va *videoAbuseReportReason) List(
parts []string, output string, writer io.Writer,
) error {
videoAbuseReportReasons, err := va.Get(parts)
if err != nil {
return err
}
switch output {
case "json":
utils.PrintJSON(videoAbuseReportReasons, nil)
utils.PrintJSON(videoAbuseReportReasons, writer)
case "yaml":
utils.PrintYAML(videoAbuseReportReasons, nil)
utils.PrintYAML(videoAbuseReportReasons, writer)
default:
fmt.Println("ID\tTitle")
_, _ = fmt.Fprintln(writer, "ID\tTitle")
for _, videoAbuseReportReason := range videoAbuseReportReasons {
fmt.Printf(
"%s\t%s\n", videoAbuseReportReason.Id,
videoAbuseReportReason.Snippet.Label,
_, _ = fmt.Fprintf(
writer, "%s\t%s\n",
videoAbuseReportReason.Id, videoAbuseReportReason.Snippet.Label,
)
}
}
return nil
}
func WithHL(hl string) Option {
+20 -15
View File
@@ -4,10 +4,9 @@ import (
"errors"
"fmt"
"github.com/eat-pray-ai/yutu/pkg/auth"
"log"
"github.com/eat-pray-ai/yutu/pkg/utils"
"google.golang.org/api/youtube/v3"
"io"
)
var (
@@ -22,8 +21,8 @@ type videoCategory struct {
}
type VideoCategory interface {
get([]string) []*youtube.VideoCategory
List([]string, string)
Get([]string) ([]*youtube.VideoCategory, error)
List([]string, string, io.Writer) error
}
type Option func(*videoCategory)
@@ -36,7 +35,7 @@ func NewVideoCategory(opt ...Option) VideoCategory {
return vc
}
func (vc *videoCategory) get(parts []string) []*youtube.VideoCategory {
func (vc *videoCategory) Get(parts []string) ([]*youtube.VideoCategory, error) {
call := service.VideoCategories.List(parts)
if len(vc.IDs) > 0 {
call = call.Id(vc.IDs...)
@@ -50,29 +49,35 @@ func (vc *videoCategory) get(parts []string) []*youtube.VideoCategory {
res, err := call.Do()
if err != nil {
utils.PrintJSON(vc, nil)
log.Fatalln(errors.Join(errGetVideoCategory, err))
return nil, errors.Join(errGetVideoCategory, err)
}
return res.Items
return res.Items, nil
}
func (vc *videoCategory) List(parts []string, output string) {
videoCategories := vc.get(parts)
func (vc *videoCategory) List(
parts []string, output string, writer io.Writer,
) error {
videoCategories, err := vc.Get(parts)
if err != nil {
return err
}
switch output {
case "json":
utils.PrintJSON(videoCategories, nil)
utils.PrintJSON(videoCategories, writer)
case "yaml":
utils.PrintYAML(videoCategories, nil)
utils.PrintYAML(videoCategories, writer)
default:
fmt.Println("ID\tTitle\tAssignable")
_, _ = fmt.Fprintln(writer, "ID\tTitle\tAssignable")
for _, videoCategory := range videoCategories {
fmt.Printf(
"%s\t%s\t%t\n", videoCategory.Id,
_, _ = fmt.Fprintf(
writer, "%s\t%s\t%t\n", videoCategory.Id,
videoCategory.Snippet.Title, videoCategory.Snippet.Assignable,
)
}
}
return nil
}
func WithIDs(ids []string) Option {
-1
View File
@@ -7,7 +7,6 @@ go_library(
visibility = ["//visibility:public"],
deps = [
"//pkg/auth",
"//pkg/utils",
"@org_golang_google_api//youtube/v3:youtube",
],
)
+13 -14
View File
@@ -4,9 +4,8 @@ import (
"errors"
"fmt"
"github.com/eat-pray-ai/yutu/pkg/auth"
"github.com/eat-pray-ai/yutu/pkg/utils"
"google.golang.org/api/youtube/v3"
"log"
"io"
"os"
)
@@ -27,8 +26,8 @@ type watermark struct {
}
type Watermark interface {
Set()
Unset()
Set(io.Writer) error
Unset(io.Writer) error
}
type Option func(*watermark)
@@ -43,12 +42,12 @@ func NewWatermark(opts ...Option) Watermark {
return w
}
func (w *watermark) Set() {
func (w *watermark) Set(writer io.Writer) error {
file, err := os.Open(w.File)
if err != nil {
utils.PrintJSON(w, nil)
log.Fatalln(errors.Join(errSetWatermark, err))
return errors.Join(errSetWatermark, err)
}
defer file.Close()
inVideoBranding := &youtube.InvideoBranding{
Position: &youtube.InvideoPosition{},
@@ -75,14 +74,14 @@ func (w *watermark) Set() {
err = call.Do()
if err != nil {
utils.PrintJSON(w, nil)
log.Fatalln(errors.Join(errSetWatermark, err))
return errors.Join(errSetWatermark, err)
}
fmt.Printf("Watermark set for channel %s\n", w.ChannelId)
_, _ = fmt.Fprintf(writer, "Watermark set for channel %s\n", w.ChannelId)
return nil
}
func (w *watermark) Unset() {
func (w *watermark) Unset(writer io.Writer) error {
call := service.Watermarks.Unset(w.ChannelId)
if w.OnBehalfOfContentOwner != "" {
call = call.OnBehalfOfContentOwner(w.OnBehalfOfContentOwner)
@@ -90,11 +89,11 @@ func (w *watermark) Unset() {
err := call.Do()
if err != nil {
utils.PrintJSON(w, nil)
log.Fatalln(errors.Join(errUnsetWatermark, err))
return errors.Join(errUnsetWatermark, err)
}
fmt.Printf("Watermark unset for channel %s\n", w.ChannelId)
_, _ = fmt.Fprintf(writer, "Watermark unset for channel %s\n", w.ChannelId)
return nil
}
func WithChannelId(channelId string) Option {