🐛 Preserve omitted non-video metadata

This commit is contained in:
OpenWaygate committed 2026-09-12 18:23:17 +08:00
1 parent 49e092ea2e
commit 70aa122710
38 files changed
+243 -166

No files matched your search

+1
View File
@@ -21,6 +21,7 @@ go_library(
deps = [
"//pkg",
"//pkg/auth",
"//pkg/common",
"@com_github_eat_pray_ai_cobra_mcp//:cobra-mcp",
"@com_github_modelcontextprotocol_go_sdk//mcp",
"@com_github_savioxavier_termlink//:termlink",
-1
View File
@@ -21,6 +21,5 @@ go_library(
"@com_github_google_jsonschema_go//jsonschema",
"@com_github_modelcontextprotocol_go_sdk//mcp",
"@com_github_spf13_cobra//:cobra",
"@com_github_spf13_pflag//:pflag",
],
)
+12 -5
View File
@@ -7,7 +7,6 @@ import (
"github.com/eat-pray-ai/yutu/cmd"
"github.com/eat-pray-ai/yutu/pkg/utils"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
const (
@@ -53,7 +52,7 @@ var captionCmd = &cobra.Command{
Short: short,
Long: long,
PersistentPreRun: func(cmd *cobra.Command, _ []string) {
resetFlags(cmd.Flags())
resetFlags(cmd)
},
Run: func(cmd *cobra.Command, _ []string) {
_ = cmd.Help()
@@ -64,14 +63,22 @@ func init() {
cmd.RootCmd.AddCommand(captionCmd)
}
func resetFlags(flagSet *pflag.FlagSet) {
boolMap := map[string]**bool{
func resetFlags(cmd *cobra.Command) {
flagSet := cmd.Flags()
boolFlags := map[string]**bool{
"isAutoSynced": &isAutoSynced,
"isCC": &isCC,
"isDraft": &isDraft,
"isEasyReader": &isEasyReader,
"isLarge": &isLarge,
}
utils.ResetFlags(boolFlags, flagSet)
utils.ResetFlags(boolMap, flagSet)
if cmd.Name() == "update" {
stringFlags := map[string]*string{
"audioTrackType": &audioTrackType,
"trackKind": &trackKind,
}
utils.ResetFlags(stringFlags, flagSet)
}
}
+2 -3
View File
@@ -38,7 +38,7 @@ var updateInSchema = &jsonschema.Schema{
"file": {Type: "string", Description: fileUsage},
"audio_track_type": {
Type: "string", Description: attUsage,
Default: jsontext.Value(`"unknown"`),
Enum: []any{"unknown", "primary", "commentary", "descriptive"},
},
"is_auto_synced": {Type: "boolean", Description: iasUsage},
"is_cc": {Type: "boolean", Description: iscUsage},
@@ -49,8 +49,7 @@ var updateInSchema = &jsonschema.Schema{
"name": {Type: "string", Description: nameUsage},
"track_kind": {
Type: "string", Description: tkUsage,
Enum: []any{"standard", "ASR", "forced"},
Default: jsontext.Value(`"standard"`),
Enum: []any{"standard", "ASR", "forced"},
},
"video_id": {Type: "string", Description: vidUsage},
"on_behalf_of": {Type: "string", Description: pkg.OBOUsage},
+12 -3
View File
@@ -5,6 +5,7 @@ package channel
import (
"github.com/eat-pray-ai/yutu/cmd"
"github.com/eat-pray-ai/yutu/pkg/utils"
"github.com/spf13/cobra"
)
@@ -31,10 +32,10 @@ var (
ids []string
channelFor string
maxResults int64
country string
country = new("")
customUrl string
defaultLanguage string
description string
defaultLanguage = new("")
description = new("")
title string
parts []string
@@ -45,6 +46,14 @@ var channelCmd = &cobra.Command{
Use: "channel",
Short: short,
Long: long,
PersistentPreRun: func(cmd *cobra.Command, _ []string) {
stringFlags := map[string]**string{
"country": &country,
"defaultLanguage": &defaultLanguage,
"description": &description,
}
utils.ResetFlags(stringFlags, cmd.Flags())
},
Run: func(cmd *cobra.Command, _ []string) {
_ = cmd.Help()
},
+3 -5
View File
@@ -77,14 +77,12 @@ func init() {
channelCmd.AddCommand(updateCmd)
updateCmd.Flags().StringSliceVarP(&ids, "id", "i", []string{}, updateIdUsage)
updateCmd.Flags().StringVarP(&country, "country", "c", "", countryUsage)
updateCmd.Flags().StringVarP(country, "country", "c", "", countryUsage)
updateCmd.Flags().StringVarP(&customUrl, "customUrl", "u", "", curlUsage)
updateCmd.Flags().StringVarP(
&defaultLanguage, "defaultLanguage", "l", "", dlUsage,
)
updateCmd.Flags().StringVarP(
&description, "description", "d", "", descUsage,
defaultLanguage, "defaultLanguage", "l", "", dlUsage,
)
updateCmd.Flags().StringVarP(description, "description", "d", "", descUsage)
updateCmd.Flags().StringVarP(&title, "title", "t", "", titleUsage)
updateCmd.Flags().StringP("output", "o", "", pkg.SilentUsage)
updateCmd.Flags().Bool("yes", false, pkg.ConfirmedUsage)
-1
View File
@@ -23,6 +23,5 @@ go_library(
"@com_github_google_jsonschema_go//jsonschema",
"@com_github_modelcontextprotocol_go_sdk//mcp",
"@com_github_spf13_cobra//:cobra",
"@com_github_spf13_pflag//:pflag",
],
)
+1 -1
View File
@@ -81,7 +81,7 @@ func init() {
liveBroadcastCmd.AddCommand(insertCmd)
insertCmd.Flags().StringVarP(&title, "title", "t", "", titleUsage)
insertCmd.Flags().StringVarP(&description, "description", "d", "", descUsage)
insertCmd.Flags().StringVarP(description, "description", "d", "", descUsage)
insertCmd.Flags().StringVarP(
&scheduledStartTime, "scheduledStartTime", "S", "", sstUsage,
)
+9 -3
View File
@@ -42,9 +42,15 @@ var insertCuepointInSchema = &jsonschema.Schema{
Type: "string", Enum: []any{"cueTypeAd"},
Description: ctUsage,
},
"cue_duration_secs": {Type: "number", Description: cdsUsage},
"cue_insertion_offset_ms": {Type: "number", Description: ciomUsage},
"cue_walltime_ms": {Type: "number", Description: cwmUsage},
"cue_duration_secs": {
Type: "number", Description: cdsUsage, Minimum: new(float64(0)),
},
"cue_insertion_offset_ms": {
Type: "number", Description: ciomUsage, Minimum: new(float64(0)),
},
"cue_walltime_ms": {
Type: "number", Description: cwmUsage, Minimum: new(float64(0)),
},
"on_behalf_of_content_owner": {Type: "string", Description: pkg.OBOCOUsage},
"on_behalf_of_content_owner_channel": {
Type: "string", Description: obococUsage,
+4 -1
View File
@@ -30,7 +30,7 @@ const (
var (
ids []string
title string
description string
description = new("")
mine = new(false)
broadcastStatus string
broadcastType string
@@ -54,6 +54,9 @@ var liveBroadcastCmd = &cobra.Command{
Long: long,
PersistentPreRun: func(cmd *cobra.Command, _ []string) {
utils.ResetFlags(map[string]**bool{"mine": &mine}, cmd.Flags())
utils.ResetFlags(
map[string]**string{"description": &description}, cmd.Flags(),
)
},
Run: func(cmd *cobra.Command, _ []string) {
_ = cmd.Help()
+1 -1
View File
@@ -84,7 +84,7 @@ func init() {
updateCmd.Flags().StringSliceVarP(&ids, "id", "i", []string{}, updateIdUsage)
updateCmd.Flags().StringVarP(&title, "title", "t", "", titleUsage)
updateCmd.Flags().StringVarP(&description, "description", "d", "", descUsage)
updateCmd.Flags().StringVarP(description, "description", "d", "", descUsage)
updateCmd.Flags().StringVarP(
&scheduledStartTime, "scheduledStartTime", "S", "", sstUsage,
)
+7 -2
View File
@@ -35,8 +35,13 @@ var insertInSchema = &jsonschema.Schema{
Properties: map[string]*jsonschema.Schema{
"live_chat_id": {Type: "string", Description: lcidUsage},
"banned_user_channel_id": {Type: "string", Description: bucidUsage},
"ban_type": {Type: "string", Description: banTypeUsage},
"ban_duration_seconds": {Type: "number", Description: banDurationUsage},
"ban_type": {
Type: "string", Description: banTypeUsage,
Enum: []any{"permanent", "temporary"},
},
"ban_duration_seconds": {
Type: "number", Description: banDurationUsage, Minimum: new(float64(0)),
},
"parts": {
Type: "array", Description: "Parts to include in the response",
Items: &jsonschema.Schema{Type: "string"}, Default: jsontext.Value(`["snippet"]`),
-1
View File
@@ -20,6 +20,5 @@ go_library(
"@com_github_google_jsonschema_go//jsonschema",
"@com_github_modelcontextprotocol_go_sdk//mcp",
"@com_github_spf13_cobra//:cobra",
"@com_github_spf13_pflag//:pflag",
],
)
+1 -1
View File
@@ -87,7 +87,7 @@ func init() {
liveStreamCmd.AddCommand(insertCmd)
insertCmd.Flags().StringVarP(&title, "title", "t", "", titleUsage)
insertCmd.Flags().StringVarP(&description, "description", "d", "", descUsage)
insertCmd.Flags().StringVarP(description, "description", "d", "", descUsage)
insertCmd.Flags().StringVarP(&frameRate, "frameRate", "f", "", frUsage)
insertCmd.Flags().StringVarP(&ingestionType, "ingestionType", "I", "", itUsage)
insertCmd.Flags().StringVarP(&resolution, "resolution", "r", "", resUsage)
+4 -1
View File
@@ -23,7 +23,7 @@ const (
var (
ids []string
title string
description string
description = new("")
mine = new(false)
frameRate string
ingestionType string
@@ -40,6 +40,9 @@ var liveStreamCmd = &cobra.Command{
Long: long,
PersistentPreRun: func(cmd *cobra.Command, _ []string) {
utils.ResetFlags(map[string]**bool{"mine": &mine}, cmd.Flags())
utils.ResetFlags(
map[string]**string{"description": &description}, cmd.Flags(),
)
},
Run: func(cmd *cobra.Command, _ []string) {
_ = cmd.Help()
+1 -1
View File
@@ -90,7 +90,7 @@ func init() {
updateCmd.Flags().StringSliceVarP(&ids, "id", "i", []string{}, updateIdUsage)
updateCmd.Flags().StringVarP(&title, "title", "t", "", titleUsage)
updateCmd.Flags().StringVarP(&description, "description", "d", "", descUsage)
updateCmd.Flags().StringVarP(description, "description", "d", "", descUsage)
updateCmd.Flags().StringVarP(&frameRate, "frameRate", "f", "", frUsage)
updateCmd.Flags().StringVarP(&ingestionType, "ingestionType", "I", "", itUsage)
updateCmd.Flags().StringVarP(&resolution, "resolution", "r", "", resUsage)
+2 -2
View File
@@ -79,9 +79,9 @@ func init() {
playlistCmd.AddCommand(insertCmd)
insertCmd.Flags().StringVarP(&title, "title", "t", "", titleUsage)
insertCmd.Flags().StringVarP(&description, "description", "d", "", descUsage)
insertCmd.Flags().StringVarP(description, "description", "d", "", descUsage)
insertCmd.Flags().StringSliceVarP(&tags, "tags", "a", []string{}, tagsUsage)
insertCmd.Flags().StringVarP(&language, "language", "l", "", languageUsage)
insertCmd.Flags().StringVarP(language, "language", "l", "", languageUsage)
insertCmd.Flags().StringVarP(&channelId, "channelId", "c", "", insertCidUsage)
insertCmd.Flags().StringVarP(&privacy, "privacy", "p", "", privacyUsage)
insertCmd.Flags().StringP("output", "o", "", pkg.SilentUsage)
+9 -2
View File
@@ -25,12 +25,12 @@ const (
var (
ids []string
title string
description string
description = new("")
hl string
maxResults int64
mine = new(false)
tags []string
language string
language = new("")
channelId string
privacy string
parts []string
@@ -45,6 +45,13 @@ var playlistCmd = &cobra.Command{
Long: long,
PersistentPreRun: func(cmd *cobra.Command, _ []string) {
utils.ResetFlags(map[string]**bool{"mine": &mine}, cmd.Flags())
utils.ResetFlags(map[string]*[]string{"tags": &tags}, cmd.Flags())
stringFlags := map[string]**string{
"description": &description,
"language": &language,
}
utils.ResetFlags(stringFlags, cmd.Flags())
},
Run: func(cmd *cobra.Command, _ []string) {
_ = cmd.Help()
+2 -2
View File
@@ -86,9 +86,9 @@ func init() {
updateCmd.Flags().StringSliceVarP(&ids, "id", "i", []string{}, updateIdUsage)
updateCmd.Flags().StringVarP(&title, "title", "t", "", titleUsage)
updateCmd.Flags().StringVarP(&description, "description", "d", "", descUsage)
updateCmd.Flags().StringVarP(description, "description", "d", "", descUsage)
updateCmd.Flags().StringSliceVarP(&tags, "tags", "a", []string{}, tagsUsage)
updateCmd.Flags().StringVarP(&language, "language", "l", "", languageUsage)
updateCmd.Flags().StringVarP(language, "language", "l", "", languageUsage)
updateCmd.Flags().StringVarP(&privacy, "privacy", "p", "", privacyUsage)
updateCmd.Flags().StringP("output", "o", "", pkg.SilentUsage)
updateCmd.Flags().Bool("yes", false, pkg.ConfirmedUsage)
+1 -1
View File
@@ -81,7 +81,7 @@ func init() {
playlistItemCmd.AddCommand(insertCmd)
insertCmd.Flags().StringVarP(&title, "title", "t", "", titleUsage)
insertCmd.Flags().StringVarP(&description, "description", "d", "", descUsage)
insertCmd.Flags().StringVarP(description, "description", "d", "", descUsage)
insertCmd.Flags().StringVarP(&kind, "kind", "k", "", kindUsage)
insertCmd.Flags().StringVarP(&kVideoId, "kVideoId", "V", "", kvidUsage)
insertCmd.Flags().StringVarP(&kChannelId, "kChannelId", "C", "", kcidUsage)
+7 -1
View File
@@ -5,6 +5,7 @@ package playlistItem
import (
"github.com/eat-pray-ai/yutu/cmd"
"github.com/eat-pray-ai/yutu/pkg/utils"
"github.com/spf13/cobra"
)
@@ -25,7 +26,7 @@ const (
var (
ids []string
title string
description string
description = new("")
kind string
kVideoId string
kChannelId string
@@ -44,6 +45,11 @@ var playlistItemCmd = &cobra.Command{
Use: "playlistItem",
Short: short,
Long: long,
PersistentPreRun: func(cmd *cobra.Command, _ []string) {
utils.ResetFlags(
map[string]**string{"description": &description}, cmd.Flags(),
)
},
Run: func(cmd *cobra.Command, _ []string) {
_ = cmd.Help()
},
+1 -1
View File
@@ -80,7 +80,7 @@ func init() {
updateCmd.Flags().StringSliceVarP(&ids, "id", "i", []string{}, updateIdUsage)
updateCmd.Flags().StringVarP(&title, "title", "t", "", titleUsage)
updateCmd.Flags().StringVarP(&description, "description", "d", "", descUsage)
updateCmd.Flags().StringVarP(description, "description", "d", "", descUsage)
updateCmd.Flags().StringVarP(&privacy, "privacy", "p", "", privacyUsage)
updateCmd.Flags().StringVarP(
&onBehalfOfContentOwner, "onBehalfOfContentOwner", "b", "", pkg.OBOCOUsage,
+8 -1
View File
@@ -59,6 +59,10 @@ var listInSchema = &jsonschema.Schema{
"order": {
Type: "string", Description: orderUsage,
Default: jsontext.Value(`"relevance"`),
Enum: []any{
"searchSortUnspecified", "date", "rating",
"viewCount", "relevance", "title", "videoCount",
},
},
"published_after": {Type: "string", Description: paUsage},
"published_before": {Type: "string", Description: pbUsage},
@@ -85,7 +89,10 @@ var listInSchema = &jsonschema.Schema{
Default: jsontext.Value(`"any"`),
},
"video_category_id": {Type: "string", Description: vcidUsage},
"video_definition": {Type: "string", Description: vdeUsage},
"video_definition": {
Type: "string", Description: vdeUsage,
Enum: []any{"any", "high", "standard"},
},
"video_dimension": {
Type: "string", Enum: []any{"any", "2d", "3d"},
Description: vdiUsage, Default: jsontext.Value(`"any"`),
+1 -1
View File
@@ -17,7 +17,7 @@ const (
forUsage = "mine|developer|contentOwner"
locationUsage = "Filter on location of the video"
lrUsage = "Filter on distance from the location"
orderUsage = "searchSortUnspecified, date, rating, viewCount, relevance, title, videoCount"
orderUsage = "searchSortUnspecified|date|rating|viewCount|relevance|title|videoCount"
paUsage = "Filter on resources published after this date"
pbUsage = "Filter on resources published before this date"
qUsage = "Textual search terms to match"
+2 -2
View File
@@ -40,8 +40,8 @@ var setInSchema = &jsonschema.Schema{
Type: "string", Description: ivpUsage,
Enum: []any{"topLeft", "topRight", "bottomLeft", "bottomRight"},
},
"duration_ms": {Type: "number", Description: dmUsage},
"offset_ms": {Type: "number", Description: omUsage},
"duration_ms": {Type: "number", Description: dmUsage, Minimum: new(float64(0))},
"offset_ms": {Type: "number", Description: omUsage, Minimum: new(float64(0))},
"offset_type": {
Type: "string", Description: otUsage,
Enum: []any{"offsetFromStart", "offsetFromEnd"},
+18 -2
View File
@@ -60,7 +60,6 @@ func NewCaption(opts ...Option) ICaption[youtube.Caption] {
return c
}
func (c *Caption) Get() ([]*youtube.Caption, error) {
if err := c.EnsureService(); err != nil {
return nil, err
@@ -159,18 +158,33 @@ func (c *Caption) Update(writer io.Writer) error {
}
if c.IsAutoSynced != nil {
caption.Snippet.IsAutoSynced = *c.IsAutoSynced
caption.Snippet.ForceSendFields = append(
caption.Snippet.ForceSendFields, "IsAutoSynced",
)
}
if c.IsCC != nil {
caption.Snippet.IsCC = *c.IsCC
caption.Snippet.ForceSendFields = append(
caption.Snippet.ForceSendFields, "IsCC",
)
}
if c.IsDraft != nil {
caption.Snippet.IsDraft = *c.IsDraft
caption.Snippet.ForceSendFields = append(
caption.Snippet.ForceSendFields, "IsDraft",
)
}
if c.IsEasyReader != nil {
caption.Snippet.IsEasyReader = *c.IsEasyReader
caption.Snippet.ForceSendFields = append(
caption.Snippet.ForceSendFields, "IsEasyReader",
)
}
if c.IsLarge != nil {
caption.Snippet.IsLarge = *c.IsLarge
caption.Snippet.ForceSendFields = append(
caption.Snippet.ForceSendFields, "IsLarge",
)
}
if c.Language != "" {
caption.Snippet.Language = c.Language
@@ -266,7 +280,9 @@ func (c *Caption) Download(writer io.Writer) error {
return errors.Join(errDownloadCaption, err)
}
file, err := pkg.Root.OpenFile(c.File, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
file, err := pkg.Root.OpenFile(
c.File, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600,
)
if err != nil {
return errors.Join(errDownloadCaption, err)
}
+18 -18
View File
@@ -20,15 +20,15 @@ var (
type Channel struct {
common.Fields
CategoryId string `yaml:"category_id" json:"category_id,omitempty"`
ForHandle string `yaml:"for_handle" json:"for_handle,omitempty"`
ForUsername string `yaml:"for_username" json:"for_username,omitempty"`
For string `yaml:"for" json:"for,omitempty"`
Country string `yaml:"country" json:"country,omitempty"`
CustomUrl string `yaml:"custom_url" json:"custom_url,omitempty"`
DefaultLanguage string `yaml:"default_language" json:"default_language,omitempty"`
Description string `yaml:"description" json:"description,omitempty"`
Title string `yaml:"title" json:"title,omitempty"`
CategoryId string `yaml:"category_id" json:"category_id,omitempty"`
ForHandle string `yaml:"for_handle" json:"for_handle,omitempty"`
ForUsername string `yaml:"for_username" json:"for_username,omitempty"`
For string `yaml:"for" json:"for,omitempty"`
Country *string `yaml:"country" json:"country,omitzero"`
CustomUrl string `yaml:"custom_url" json:"custom_url,omitempty"`
DefaultLanguage *string `yaml:"default_language" json:"default_language,omitzero"`
Description *string `yaml:"description" json:"description,omitzero"`
Title string `yaml:"title" json:"title,omitempty"`
}
type IChannel[T youtube.Channel] interface {
@@ -119,17 +119,17 @@ func (c *Channel) Update(writer io.Writer) error {
}
cha := channels[0]
if c.Country != "" {
cha.Snippet.Country = c.Country
if c.Country != nil {
cha.Snippet.Country = *c.Country
}
if c.CustomUrl != "" {
cha.Snippet.CustomUrl = c.CustomUrl
}
if c.DefaultLanguage != "" {
cha.Snippet.DefaultLanguage = c.DefaultLanguage
if c.DefaultLanguage != nil {
cha.Snippet.DefaultLanguage = *c.DefaultLanguage
}
if c.Description != "" {
cha.Snippet.Description = c.Description
if c.Description != nil {
cha.Snippet.Description = *c.Description
}
if c.Title != "" {
cha.Snippet.Title = c.Title
@@ -169,7 +169,7 @@ func WithFor(f string) Option {
}
}
func WithCountry(country string) Option {
func WithCountry(country *string) Option {
return func(c *Channel) {
c.Country = country
}
@@ -181,13 +181,13 @@ func WithCustomUrl(url string) Option {
}
}
func WithDefaultLanguage(language string) Option {
func WithDefaultLanguage(language *string) Option {
return func(c *Channel) {
c.DefaultLanguage = language
}
}
func WithDescription(desc string) Option {
func WithDescription(desc *string) Option {
return func(c *Channel) {
c.Description = desc
}
+17 -17
View File
@@ -39,10 +39,10 @@ func TestNewChannel(t *testing.T) {
WithFor("managedByMe"),
WithMaxResults(100),
WithOnBehalfOfContentOwner("owner123"),
WithCountry("US"),
WithCountry(new("US")),
WithCustomUrl("testchannel"),
WithDefaultLanguage("en"),
WithDescription("Test channel description"),
WithDefaultLanguage(new("en")),
WithDescription(new("Test channel description")),
WithTitle("Test Channel"),
WithParts([]string{"snippet", "contentDetails"}),
WithOutput("json"),
@@ -61,10 +61,10 @@ func TestNewChannel(t *testing.T) {
ForHandle: "@testhandle",
ForUsername: "testuser",
For: "managedByMe",
Country: "US",
Country: new("US"),
CustomUrl: "testchannel",
DefaultLanguage: "en",
Description: "Test channel description",
DefaultLanguage: new("en"),
Description: new("Test channel description"),
Title: "Test Channel",
},
},
@@ -137,10 +137,10 @@ func TestNewChannel(t *testing.T) {
WithForUsername(""),
WithHl(""),
WithOnBehalfOfContentOwner(""),
WithCountry(""),
WithCountry(new("")),
WithCustomUrl(""),
WithDefaultLanguage(""),
WithDescription(""),
WithDefaultLanguage(new("")),
WithDescription(new("")),
WithTitle(""),
WithService(svc),
},
@@ -150,10 +150,10 @@ func TestNewChannel(t *testing.T) {
CategoryId: "",
ForHandle: "",
ForUsername: "",
Country: "",
Country: new(""),
CustomUrl: "",
DefaultLanguage: "",
Description: "",
DefaultLanguage: new(""),
Description: new(""),
Title: "",
},
},
@@ -163,7 +163,7 @@ func TestNewChannel(t *testing.T) {
opts: []Option{
WithIds([]string{"channel1"}),
WithTitle("My Channel"),
WithCountry("UK"),
WithCountry(new("UK")),
WithMaxResults(50),
WithService(svc),
},
@@ -171,7 +171,7 @@ func TestNewChannel(t *testing.T) {
want: &Channel{
Service: svc, Ids: []string{"channel1"}, MaxResults: 50,
Title: "My Channel",
Country: "UK",
Country: new("UK"),
},
},
}
@@ -425,7 +425,7 @@ func TestChannel_Update(t *testing.T) {
opts: []Option{
WithIds([]string{"channel-id"}),
WithTitle("New Title"),
WithDescription("New Description"),
WithDescription(new("New Description")),
WithMaxResults(1),
},
verify: func(r *http.Request) {
@@ -448,9 +448,9 @@ func TestChannel_Update(t *testing.T) {
name: "update channel full",
opts: []Option{
WithIds([]string{"channel-id"}),
WithCountry("US"),
WithCountry(new("US")),
WithCustomUrl("my-url"),
WithDefaultLanguage("en"),
WithDefaultLanguage(new("en")),
WithMaxResults(1),
},
verify: func(r *http.Request) {
+3
View File
@@ -149,6 +149,9 @@ func (c *Comment) Update(writer io.Writer) error {
comment := comments[0]
if c.CanRate != nil {
comment.Snippet.CanRate = *c.CanRate
comment.Snippet.ForceSendFields = append(
comment.Snippet.ForceSendFields, "CanRate",
)
}
if c.TextOriginal != "" {
+15 -13
View File
@@ -25,15 +25,15 @@ var (
type LiveBroadcast struct {
common.Fields
Title string `yaml:"title" json:"title,omitempty"`
Description string `yaml:"description" json:"description,omitempty"`
Mine *bool `yaml:"mine" json:"mine,omitzero"`
BroadcastStatus string `yaml:"broadcast_status" json:"broadcast_status,omitempty"`
BroadcastType string `yaml:"broadcast_type" json:"broadcast_type,omitempty"`
PrivacyStatus string `yaml:"privacy_status" json:"privacy_status,omitempty"`
ScheduledStartTime string `yaml:"scheduled_start_time" json:"scheduled_start_time,omitempty"`
ScheduledEndTime string `yaml:"scheduled_end_time" json:"scheduled_end_time,omitempty"`
StreamId string `yaml:"stream_id" json:"stream_id,omitempty"`
Title string `yaml:"title" json:"title,omitempty"`
Description *string `yaml:"description" json:"description,omitzero"`
Mine *bool `yaml:"mine" json:"mine,omitzero"`
BroadcastStatus string `yaml:"broadcast_status" json:"broadcast_status,omitempty"`
BroadcastType string `yaml:"broadcast_type" json:"broadcast_type,omitempty"`
PrivacyStatus string `yaml:"privacy_status" json:"privacy_status,omitempty"`
ScheduledStartTime string `yaml:"scheduled_start_time" json:"scheduled_start_time,omitempty"`
ScheduledEndTime string `yaml:"scheduled_end_time" json:"scheduled_end_time,omitempty"`
StreamId string `yaml:"stream_id" json:"stream_id,omitempty"`
CueType string `yaml:"cue_type" json:"cue_type,omitempty"`
CueDurationSecs int64 `yaml:"cue_duration_secs" json:"cue_duration_secs,omitzero"`
@@ -129,7 +129,6 @@ func (b *LiveBroadcast) Insert(writer io.Writer) error {
broadcast := &youtube.LiveBroadcast{
Snippet: &youtube.LiveBroadcastSnippet{
Title: b.Title,
Description: b.Description,
ScheduledStartTime: b.ScheduledStartTime,
ScheduledEndTime: b.ScheduledEndTime,
},
@@ -137,6 +136,9 @@ func (b *LiveBroadcast) Insert(writer io.Writer) error {
PrivacyStatus: b.PrivacyStatus,
},
}
if b.Description != nil {
broadcast.Snippet.Description = *b.Description
}
call := b.Service.LiveBroadcasts.Insert(b.Parts, broadcast)
if b.OnBehalfOfContentOwner != "" {
@@ -188,8 +190,8 @@ func (b *LiveBroadcast) Update(writer io.Writer) error {
if b.Title != "" {
broadcast.Snippet.Title = b.Title
}
if b.Description != "" {
broadcast.Snippet.Description = b.Description
if b.Description != nil {
broadcast.Snippet.Description = *b.Description
}
if b.ScheduledStartTime != "" {
broadcast.Snippet.ScheduledStartTime = b.ScheduledStartTime
@@ -339,7 +341,7 @@ func WithTitle(title string) Option {
}
}
func WithDescription(description string) Option {
func WithDescription(description *string) Option {
return func(b *LiveBroadcast) {
b.Description = description
}
+6 -6
View File
@@ -35,7 +35,7 @@ func TestNewLiveBroadcast(t *testing.T) {
opts: []Option{
WithIds([]string{"broadcast1", "broadcast2"}),
WithTitle("Test Broadcast"),
WithDescription("A test broadcast"),
WithDescription(new("A test broadcast")),
WithMine(&mine),
WithBroadcastStatus("active"),
WithBroadcastType("event"),
@@ -63,7 +63,7 @@ func TestNewLiveBroadcast(t *testing.T) {
Ids: []string{"broadcast1", "broadcast2"},
OnBehalfOfContentOwner: "owner123",
Title: "Test Broadcast",
Description: "A test broadcast",
Description: new("A test broadcast"),
Mine: &mine,
BroadcastStatus: "active",
BroadcastType: "event",
@@ -112,7 +112,7 @@ func TestNewLiveBroadcast(t *testing.T) {
args: args{
opts: []Option{
WithTitle(""),
WithDescription(""),
WithDescription(new("")),
WithBroadcastStatus(""),
WithBroadcastType(""),
WithPrivacyStatus(""),
@@ -124,7 +124,7 @@ func TestNewLiveBroadcast(t *testing.T) {
want: &LiveBroadcast{
Fields: common.Fields{},
Title: "",
Description: "",
Description: new(""),
BroadcastStatus: "",
BroadcastType: "",
PrivacyStatus: "",
@@ -341,7 +341,7 @@ func TestLiveBroadcast_Insert(t *testing.T) {
name: "insert live broadcast",
opts: []Option{
WithTitle("New Broadcast"),
WithDescription("A new live broadcast"),
WithDescription(new("A new live broadcast")),
WithPrivacyStatus("public"),
WithScheduledStartTime("2026-01-01T00:00:00Z"),
WithScheduledEndTime("2026-01-01T01:00:00Z"),
@@ -429,7 +429,7 @@ func TestLiveBroadcast_Update(t *testing.T) {
opts: []Option{
WithIds([]string{"broadcast-1"}),
WithTitle("Updated Broadcast"),
WithDescription("Updated description"),
WithDescription(new("Updated description")),
WithMaxResults(1),
},
wantErr: false,
+13 -11
View File
@@ -22,12 +22,12 @@ var (
type LiveStream struct {
common.Fields
Title string `yaml:"title" json:"title,omitempty"`
Description string `yaml:"description" json:"description,omitempty"`
Mine *bool `yaml:"mine" json:"mine,omitzero"`
FrameRate string `yaml:"frame_rate" json:"frame_rate,omitempty"`
IngestionType string `yaml:"ingestion_type" json:"ingestion_type,omitempty"`
Resolution string `yaml:"resolution" json:"resolution,omitempty"`
Title string `yaml:"title" json:"title,omitempty"`
Description *string `yaml:"description" json:"description,omitzero"`
Mine *bool `yaml:"mine" json:"mine,omitzero"`
FrameRate string `yaml:"frame_rate" json:"frame_rate,omitempty"`
IngestionType string `yaml:"ingestion_type" json:"ingestion_type,omitempty"`
Resolution string `yaml:"resolution" json:"resolution,omitempty"`
OnBehalfOfContentOwnerChannel string `yaml:"on_behalf_of_content_owner_channel" json:"on_behalf_of_content_owner_channel,omitempty"`
}
@@ -106,8 +106,7 @@ func (s *LiveStream) Insert(writer io.Writer) error {
}
stream := &youtube.LiveStream{
Snippet: &youtube.LiveStreamSnippet{
Title: s.Title,
Description: s.Description,
Title: s.Title,
},
Cdn: &youtube.CdnSettings{
FrameRate: s.FrameRate,
@@ -115,6 +114,9 @@ func (s *LiveStream) Insert(writer io.Writer) error {
Resolution: s.Resolution,
},
}
if s.Description != nil {
stream.Snippet.Description = *s.Description
}
call := s.Service.LiveStreams.Insert(s.Parts, stream)
if s.OnBehalfOfContentOwner != "" {
@@ -166,8 +168,8 @@ func (s *LiveStream) Update(writer io.Writer) error {
if s.Title != "" {
stream.Snippet.Title = s.Title
}
if s.Description != "" {
stream.Snippet.Description = s.Description
if s.Description != nil {
stream.Snippet.Description = *s.Description
}
if s.FrameRate != "" {
stream.Cdn.FrameRate = s.FrameRate
@@ -227,7 +229,7 @@ func WithTitle(title string) Option {
}
}
func WithDescription(description string) Option {
func WithDescription(description *string) Option {
return func(s *LiveStream) {
s.Description = description
}
+6 -6
View File
@@ -35,7 +35,7 @@ func TestNewLiveStream(t *testing.T) {
opts: []Option{
WithIds([]string{"stream1", "stream2"}),
WithTitle("Test Stream"),
WithDescription("A test stream"),
WithDescription(new("A test stream")),
WithMine(&mine),
WithFrameRate("60fps"),
WithIngestionType("rtmp"),
@@ -56,7 +56,7 @@ func TestNewLiveStream(t *testing.T) {
Ids: []string{"stream1", "stream2"},
OnBehalfOfContentOwner: "owner123",
Title: "Test Stream",
Description: "A test stream",
Description: new("A test stream"),
Mine: &mine,
FrameRate: "60fps",
IngestionType: "rtmp",
@@ -98,7 +98,7 @@ func TestNewLiveStream(t *testing.T) {
args: args{
opts: []Option{
WithTitle(""),
WithDescription(""),
WithDescription(new("")),
WithFrameRate(""),
WithIngestionType(""),
WithResolution(""),
@@ -107,7 +107,7 @@ func TestNewLiveStream(t *testing.T) {
want: &LiveStream{
Fields: common.Fields{},
Title: "",
Description: "",
Description: new(""),
FrameRate: "",
IngestionType: "",
Resolution: "",
@@ -301,7 +301,7 @@ func TestLiveStream_Insert(t *testing.T) {
name: "insert live stream",
opts: []Option{
WithTitle("New Stream"),
WithDescription("A new live stream"),
WithDescription(new("A new live stream")),
WithFrameRate("60fps"),
WithIngestionType("rtmp"),
WithResolution("1080p"),
@@ -394,7 +394,7 @@ func TestLiveStream_Update(t *testing.T) {
opts: []Option{
WithIds([]string{"stream-1"}),
WithTitle("Updated Stream"),
WithDescription("Updated description"),
WithDescription(new("Updated description")),
WithMaxResults(1),
},
wantErr: false,
+17 -13
View File
@@ -23,10 +23,10 @@ var (
type Playlist struct {
common.Fields
Title string `yaml:"title" json:"title,omitempty"`
Description string `yaml:"description" json:"description,omitempty"`
Description *string `yaml:"description" json:"description,omitzero"`
Mine *bool `yaml:"mine" json:"mine,omitzero"`
Tags []string `yaml:"tags" json:"tags,omitempty"`
Language string `yaml:"language" json:"language,omitempty"`
Language *string `yaml:"language" json:"language,omitzero"`
Privacy string `yaml:"privacy" json:"privacy,omitempty"`
OnBehalfOfContentOwnerChannel string `yaml:"on_behalf_of_content_owner_channel" json:"on_behalf_of_content_owner_channel,omitempty"`
@@ -110,16 +110,20 @@ func (p *Playlist) Insert(writer io.Writer) error {
}
upload := &youtube.Playlist{
Snippet: &youtube.PlaylistSnippet{
Title: p.Title,
Description: p.Description,
Tags: p.Tags,
DefaultLanguage: p.Language,
ChannelId: p.ChannelId,
Title: p.Title,
Tags: p.Tags,
ChannelId: p.ChannelId,
},
Status: &youtube.PlaylistStatus{
PrivacyStatus: p.Privacy,
},
}
if p.Description != nil {
upload.Snippet.Description = *p.Description
}
if p.Language != nil {
upload.Snippet.DefaultLanguage = *p.Language
}
call := p.Service.Playlists.Insert([]string{"snippet", "status"}, upload)
if p.OnBehalfOfContentOwner != "" {
@@ -153,14 +157,14 @@ func (p *Playlist) Update(writer io.Writer) error {
if p.Title != "" {
playlist.Snippet.Title = p.Title
}
if p.Description != "" {
playlist.Snippet.Description = p.Description
if p.Description != nil {
playlist.Snippet.Description = *p.Description
}
if p.Tags != nil {
playlist.Snippet.Tags = p.Tags
}
if p.Language != "" {
playlist.Snippet.DefaultLanguage = p.Language
if p.Language != nil {
playlist.Snippet.DefaultLanguage = *p.Language
}
if p.Privacy != "" {
playlist.Status.PrivacyStatus = p.Privacy
@@ -204,7 +208,7 @@ func WithTitle(title string) Option {
}
}
func WithDescription(description string) Option {
func WithDescription(description *string) Option {
return func(p *Playlist) {
p.Description = description
}
@@ -216,7 +220,7 @@ func WithTags(tags []string) Option {
}
}
func WithLanguage(language string) Option {
func WithLanguage(language *string) Option {
return func(p *Playlist) {
p.Language = language
}
+13 -13
View File
@@ -37,9 +37,9 @@ func TestNewPlaylist(t *testing.T) {
opts: []Option{
WithIds([]string{"playlist1", "playlist2"}),
WithTitle("Test Playlist"),
WithDescription("Test playlist description"),
WithDescription(new("Test playlist description")),
WithTags([]string{"tag1", "tag2", "tag3"}),
WithLanguage("en"),
WithLanguage(new("en")),
WithChannelId("channel123"),
WithPrivacy("public"),
WithHl("en"),
@@ -62,9 +62,9 @@ func TestNewPlaylist(t *testing.T) {
ChannelId: "channel123",
OnBehalfOfContentOwner: "owner123",
Title: "Test Playlist",
Description: "Test playlist description",
Description: new("Test playlist description"),
Tags: []string{"tag1", "tag2", "tag3"},
Language: "en",
Language: new("en"),
Privacy: "public",
Mine: &mineTrue,
OnBehalfOfContentOwnerChannel: "ownerChannel123",
@@ -125,8 +125,8 @@ func TestNewPlaylist(t *testing.T) {
args: args{
opts: []Option{
WithTitle(""),
WithDescription(""),
WithLanguage(""),
WithDescription(new("")),
WithLanguage(new("")),
WithChannelId(""),
WithPrivacy(""),
WithHl(""),
@@ -137,8 +137,8 @@ func TestNewPlaylist(t *testing.T) {
want: &Playlist{
Fields: common.Fields{},
Title: "",
Description: "",
Language: "",
Description: new(""),
Language: new(""),
Privacy: "",
OnBehalfOfContentOwnerChannel: "",
},
@@ -148,7 +148,7 @@ func TestNewPlaylist(t *testing.T) {
args: args{
opts: []Option{
WithTitle("My Playlist"),
WithDescription("A great playlist"),
WithDescription(new("A great playlist")),
WithPrivacy("private"),
WithMaxResults(25),
},
@@ -156,7 +156,7 @@ func TestNewPlaylist(t *testing.T) {
want: &Playlist{
MaxResults: 25,
Title: "My Playlist",
Description: "A great playlist",
Description: new("A great playlist"),
Privacy: "private",
},
},
@@ -364,7 +364,7 @@ func TestPlaylist_Insert(t *testing.T) {
name: "insert playlist",
opts: []Option{
WithTitle("New Playlist"),
WithDescription("Description"),
WithDescription(new("Description")),
WithPrivacy("public"),
},
verify: func(r *http.Request) {
@@ -436,9 +436,9 @@ func TestPlaylist_Update(t *testing.T) {
opts: []Option{
WithIds([]string{"playlist-id"}),
WithTitle("Updated Title"),
WithDescription("Updated Description"),
WithDescription(new("Updated Description")),
WithTags([]string{"tag1", "tag2"}),
WithLanguage("en"),
WithLanguage(new("en")),
WithPrivacy("private"),
WithOnBehalfOfContentOwner("owner-id"),
WithMaxResults(1),
+19 -17
View File
@@ -22,15 +22,15 @@ var (
type PlaylistItem struct {
common.Fields
Title string `yaml:"title" json:"title,omitempty"`
Description string `yaml:"description" json:"description,omitempty"`
Kind string `yaml:"kind" json:"kind,omitempty"`
KVideoId string `yaml:"k_video_id" json:"k_video_id,omitempty"`
KChannelId string `yaml:"k_channel_id" json:"k_channel_id,omitempty"`
KPlaylistId string `yaml:"k_playlist_id" json:"k_playlist_id,omitempty"`
VideoId string `yaml:"video_id" json:"video_id,omitempty"`
PlaylistId string `yaml:"playlist_id" json:"playlist_id,omitempty"`
Privacy string `yaml:"privacy" json:"privacy,omitempty"`
Title string `yaml:"title" json:"title,omitempty"`
Description *string `yaml:"description" json:"description,omitzero"`
Kind string `yaml:"kind" json:"kind,omitempty"`
KVideoId string `yaml:"k_video_id" json:"k_video_id,omitempty"`
KChannelId string `yaml:"k_channel_id" json:"k_channel_id,omitempty"`
KPlaylistId string `yaml:"k_playlist_id" json:"k_playlist_id,omitempty"`
VideoId string `yaml:"video_id" json:"video_id,omitempty"`
PlaylistId string `yaml:"playlist_id" json:"playlist_id,omitempty"`
Privacy string `yaml:"privacy" json:"privacy,omitempty"`
}
type IPlaylistItem[T any] interface {
@@ -135,16 +135,18 @@ func (pi *PlaylistItem) Insert(writer io.Writer) error {
playlistItem := &youtube.PlaylistItem{
Snippet: &youtube.PlaylistItemSnippet{
Title: pi.Title,
Description: pi.Description,
ResourceId: resourceId,
PlaylistId: pi.PlaylistId,
ChannelId: pi.ChannelId,
Title: pi.Title,
ResourceId: resourceId,
PlaylistId: pi.PlaylistId,
ChannelId: pi.ChannelId,
},
Status: &youtube.PlaylistItemStatus{
PrivacyStatus: pi.Privacy,
},
}
if pi.Description != nil {
playlistItem.Snippet.Description = *pi.Description
}
call := pi.Service.PlaylistItems.Insert(
[]string{"snippet", "status"}, playlistItem,
@@ -182,8 +184,8 @@ func (pi *PlaylistItem) Update(writer io.Writer) error {
if pi.Title != "" {
playlistItem.Snippet.Title = pi.Title
}
if pi.Description != "" {
playlistItem.Snippet.Description = pi.Description
if pi.Description != nil {
playlistItem.Snippet.Description = *pi.Description
}
if pi.Privacy != "" {
playlistItem.Status.PrivacyStatus = pi.Privacy
@@ -233,7 +235,7 @@ func WithTitle(title string) Option {
}
}
func WithDescription(description string) Option {
func WithDescription(description *string) Option {
return func(p *PlaylistItem) {
p.Description = description
}
+5 -5
View File
@@ -34,7 +34,7 @@ func TestNewPlaylistItem(t *testing.T) {
opts: []Option{
WithIds([]string{"item1", "item2"}),
WithTitle("Test Item"),
WithDescription("Test item description"),
WithDescription(new("Test item description")),
WithKind("video"),
WithKVideoId("video123"),
WithKChannelId("channel123"),
@@ -59,7 +59,7 @@ func TestNewPlaylistItem(t *testing.T) {
ChannelId: "channel456",
OnBehalfOfContentOwner: "owner123",
Title: "Test Item",
Description: "Test item description",
Description: new("Test item description"),
Kind: "video",
KVideoId: "video123",
KChannelId: "channel123",
@@ -103,7 +103,7 @@ func TestNewPlaylistItem(t *testing.T) {
args: args{
opts: []Option{
WithTitle(""),
WithDescription(""),
WithDescription(new("")),
WithKind(""),
WithKVideoId(""),
WithKChannelId(""),
@@ -121,7 +121,7 @@ func TestNewPlaylistItem(t *testing.T) {
ChannelId: "",
OnBehalfOfContentOwner: "",
Title: "",
Description: "",
Description: new(""),
Kind: "",
KVideoId: "",
KChannelId: "",
@@ -489,7 +489,7 @@ func TestPlaylistItem_Update(t *testing.T) {
name: "update playlist item description and privacy",
opts: []Option{
WithIds([]string{"item-id"}),
WithDescription("Updated Description"),
WithDescription(new("Updated Description")),
WithPrivacy("private"),
WithMaxResults(1),
},
+2 -2
View File
@@ -265,7 +265,7 @@ func (v *Video) Insert(writer io.Writer) error {
if v.PlaylistId != "" {
pi := playlistItem.NewPlaylistItem(
playlistItem.WithTitle(res.Snippet.Title),
playlistItem.WithDescription(res.Snippet.Description),
playlistItem.WithDescription(&res.Snippet.Description),
playlistItem.WithKind("video"),
playlistItem.WithKVideoId(res.Id),
playlistItem.WithPlaylistId(v.PlaylistId),
@@ -399,7 +399,7 @@ func (v *Video) Update(writer io.Writer) error {
if v.PlaylistId != "" {
pi := playlistItem.NewPlaylistItem(
playlistItem.WithTitle(res.Snippet.Title),
playlistItem.WithDescription(res.Snippet.Description),
playlistItem.WithDescription(&res.Snippet.Description),
playlistItem.WithKind("video"),
playlistItem.WithKVideoId(res.Id),
playlistItem.WithPlaylistId(v.PlaylistId),