✨ Support pagination when list
This commit is contained in:
1 parent
5bf60ff2f1
commit
a74fca8ce7
21 files changed
+343
-206
No files matched your search
+26
-11
@@ -27,14 +27,14 @@ type activity struct {
|
||||
RegionCode string `yaml:"region_code" json:"region_code"`
|
||||
}
|
||||
|
||||
type Activity interface {
|
||||
type Activity[T any] interface {
|
||||
List([]string, string, string, io.Writer) error
|
||||
Get([]string) ([]*youtube.Activity, error)
|
||||
Get([]string) ([]*T, error)
|
||||
}
|
||||
|
||||
type Option func(*activity)
|
||||
|
||||
func NewActivity(opts ...Option) Activity {
|
||||
func NewActivity(opts ...Option) Activity[youtube.Activity] {
|
||||
a := &activity{}
|
||||
|
||||
for _, opt := range opts {
|
||||
@@ -58,9 +58,8 @@ func (a *activity) Get(parts []string) ([]*youtube.Activity, error) {
|
||||
call = call.Mine(*a.Mine)
|
||||
}
|
||||
|
||||
call.MaxResults(a.MaxResults)
|
||||
|
||||
if a.PublishedAfter != "" {
|
||||
// TODO: update call
|
||||
call.PublishedAfter(a.PublishedAfter)
|
||||
}
|
||||
|
||||
@@ -72,19 +71,35 @@ func (a *activity) Get(parts []string) ([]*youtube.Activity, error) {
|
||||
call.RegionCode(a.RegionCode)
|
||||
}
|
||||
|
||||
res, err := call.Do()
|
||||
if err != nil {
|
||||
return nil, errors.Join(errGetActivity, err)
|
||||
var items []*youtube.Activity
|
||||
pageToken := ""
|
||||
for a.MaxResults > 0 {
|
||||
call = call.MaxResults(min(a.MaxResults, pkg.PerPage))
|
||||
a.MaxResults -= pkg.PerPage
|
||||
if pageToken != "" {
|
||||
call = call.PageToken(pageToken)
|
||||
}
|
||||
|
||||
res, err := call.Do()
|
||||
if err != nil {
|
||||
return items, errors.Join(errGetActivity, err)
|
||||
}
|
||||
|
||||
items = append(items, res.Items...)
|
||||
pageToken = res.NextPageToken
|
||||
if pageToken == "" || len(res.Items) == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return res.Items, nil
|
||||
return items, nil
|
||||
}
|
||||
|
||||
func (a *activity) List(
|
||||
parts []string, output string, jpath string, writer io.Writer,
|
||||
) error {
|
||||
activities, err := a.Get(parts)
|
||||
if err != nil {
|
||||
if err != nil && activities == nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -109,7 +124,7 @@ func (a *activity) List(
|
||||
)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
func WithChannelId(channelId string) Option {
|
||||
|
||||
+14
-10
@@ -41,18 +41,18 @@ type caption struct {
|
||||
Tlang string `yaml:"tlang" json:"tlang"`
|
||||
}
|
||||
|
||||
type Caption interface {
|
||||
Get(parts []string) ([]*youtube.Caption, error)
|
||||
List(parts []string, output string, s string, writer io.Writer) error
|
||||
Insert(output string, s string, writer io.Writer) error
|
||||
Update(output string, s string, writer io.Writer) error
|
||||
Delete(writer io.Writer) error
|
||||
Download(writer io.Writer) error
|
||||
type Caption[T youtube.Caption] interface {
|
||||
Get([]string) ([]*T, error)
|
||||
List([]string, string, string, io.Writer) error
|
||||
Insert(string, string, io.Writer) error
|
||||
Update(string, string, io.Writer) error
|
||||
Delete(io.Writer) error
|
||||
Download(io.Writer) error
|
||||
}
|
||||
|
||||
type Option func(*caption)
|
||||
|
||||
func NewCation(opts ...Option) Caption {
|
||||
func NewCation(opts ...Option) Caption[youtube.Caption] {
|
||||
c := &caption{}
|
||||
for _, opt := range opts {
|
||||
opt(c)
|
||||
@@ -112,7 +112,9 @@ func (c *caption) List(
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *caption) Insert(output string, jpath string, writer io.Writer) error {
|
||||
func (c *caption) Insert(
|
||||
output string, jpath string, writer io.Writer,
|
||||
) error {
|
||||
file, err := pkg.Root.Open(c.File)
|
||||
if err != nil {
|
||||
return errors.Join(errInsertCaption, err)
|
||||
@@ -159,7 +161,9 @@ func (c *caption) Insert(output string, jpath string, writer io.Writer) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *caption) Update(output string, jpath string, writer io.Writer) error {
|
||||
func (c *caption) Update(
|
||||
output string, jpath string, writer io.Writer,
|
||||
) error {
|
||||
captions, err := c.Get([]string{"snippet"})
|
||||
if err != nil {
|
||||
return errors.Join(errUpdateCaption, err)
|
||||
|
||||
+24
-19
@@ -39,15 +39,15 @@ type channel struct {
|
||||
Title string `yaml:"title" json:"title"`
|
||||
}
|
||||
|
||||
type Channel interface {
|
||||
type Channel[T youtube.Channel] interface {
|
||||
List([]string, string, string, io.Writer) error
|
||||
Update(string, string, io.Writer) error
|
||||
Get([]string) ([]*youtube.Channel, error)
|
||||
Get([]string) ([]*T, error)
|
||||
}
|
||||
|
||||
type Option func(*channel)
|
||||
|
||||
func NewChannel(opts ...Option) Channel {
|
||||
func NewChannel(opts ...Option) Channel[youtube.Channel] {
|
||||
c := &channel{}
|
||||
|
||||
for _, opt := range opts {
|
||||
@@ -62,54 +62,59 @@ func (c *channel) Get(parts []string) ([]*youtube.Channel, error) {
|
||||
if c.CategoryId != "" {
|
||||
call = call.CategoryId(c.CategoryId)
|
||||
}
|
||||
|
||||
if c.ForHandle != "" {
|
||||
call = call.ForHandle(c.ForHandle)
|
||||
}
|
||||
|
||||
if c.ForUsername != "" {
|
||||
call = call.ForUsername(c.ForUsername)
|
||||
}
|
||||
|
||||
if c.Hl != "" {
|
||||
call = call.Hl(c.Hl)
|
||||
}
|
||||
|
||||
if len(c.IDs) > 0 {
|
||||
call = call.Id(c.IDs...)
|
||||
}
|
||||
|
||||
if c.ManagedByMe != nil {
|
||||
call = call.ManagedByMe(*c.ManagedByMe)
|
||||
}
|
||||
|
||||
call = call.MaxResults(c.MaxResults)
|
||||
|
||||
if c.Mine != nil {
|
||||
call = call.Mine(*c.Mine)
|
||||
}
|
||||
|
||||
if c.MySubscribers != nil {
|
||||
call = call.MySubscribers(*c.MySubscribers)
|
||||
}
|
||||
|
||||
if c.OnBehalfOfContentOwner != "" {
|
||||
call = call.OnBehalfOfContentOwner(c.OnBehalfOfContentOwner)
|
||||
}
|
||||
|
||||
res, err := call.Do()
|
||||
if err != nil {
|
||||
return nil, errors.Join(errGetChannel, err)
|
||||
var items []*youtube.Channel
|
||||
pageToken := ""
|
||||
for c.MaxResults > 0 {
|
||||
call = call.MaxResults(min(c.MaxResults, pkg.PerPage))
|
||||
c.MaxResults -= pkg.PerPage
|
||||
if pageToken != "" {
|
||||
call = call.PageToken(pageToken)
|
||||
}
|
||||
res, err := call.Do()
|
||||
if err != nil {
|
||||
return items, errors.Join(errGetChannel, err)
|
||||
}
|
||||
|
||||
items = append(items, res.Items...)
|
||||
pageToken = res.NextPageToken
|
||||
if pageToken == "" || len(res.Items) == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return res.Items, nil
|
||||
return items, nil
|
||||
}
|
||||
|
||||
func (c *channel) List(
|
||||
parts []string, output string, jpath string, writer io.Writer,
|
||||
) error {
|
||||
channels, err := c.Get(parts)
|
||||
if err != nil {
|
||||
if err != nil && channels == nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -131,7 +136,7 @@ func (c *channel) List(
|
||||
)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *channel) Update(output string, jpath string, writer io.Writer) error {
|
||||
|
||||
@@ -26,8 +26,8 @@ type channelSection struct {
|
||||
OnBehalfOfContentOwner string `yaml:"on_behalf_of_content_owner" json:"on_behalf_of_content_owner"`
|
||||
}
|
||||
|
||||
type ChannelSection interface {
|
||||
Get([]string) ([]*youtube.ChannelSection, error)
|
||||
type ChannelSection[T any] interface {
|
||||
Get([]string) ([]*T, error)
|
||||
List([]string, string, string, io.Writer) error
|
||||
Delete(writer io.Writer) error
|
||||
// Update()
|
||||
@@ -36,7 +36,7 @@ type ChannelSection interface {
|
||||
|
||||
type Option func(*channelSection)
|
||||
|
||||
func NewChannelSection(opts ...Option) ChannelSection {
|
||||
func NewChannelSection(opts ...Option) ChannelSection[youtube.ChannelSection] {
|
||||
cs := &channelSection{}
|
||||
|
||||
for _, opt := range opts {
|
||||
|
||||
+25
-14
@@ -38,8 +38,8 @@ type comment struct {
|
||||
ViewerRating string `yaml:"viewer_rating" json:"viewer_rating"`
|
||||
}
|
||||
|
||||
type Comment interface {
|
||||
Get([]string) ([]*youtube.Comment, error)
|
||||
type Comment[T any] interface {
|
||||
Get([]string) ([]*T, error)
|
||||
List([]string, string, string, io.Writer) error
|
||||
Insert(string, string, io.Writer) error
|
||||
Update(string, string, io.Writer) error
|
||||
@@ -50,7 +50,7 @@ type Comment interface {
|
||||
|
||||
type Option func(*comment)
|
||||
|
||||
func NewComment(opts ...Option) Comment {
|
||||
func NewComment(opts ...Option) Comment[youtube.Comment] {
|
||||
c := &comment{}
|
||||
|
||||
for _, opt := range opts {
|
||||
@@ -62,34 +62,45 @@ func NewComment(opts ...Option) Comment {
|
||||
|
||||
func (c *comment) Get(parts []string) ([]*youtube.Comment, error) {
|
||||
call := service.Comments.List(parts)
|
||||
|
||||
if c.IDs[0] != "" {
|
||||
call = call.Id(c.IDs...)
|
||||
}
|
||||
|
||||
call = call.MaxResults(c.MaxResults)
|
||||
|
||||
if c.ParentId != "" {
|
||||
call = call.ParentId(c.ParentId)
|
||||
}
|
||||
|
||||
if c.TextFormat != "" {
|
||||
call = call.TextFormat(c.TextFormat)
|
||||
}
|
||||
|
||||
res, err := call.Do()
|
||||
if err != nil {
|
||||
return nil, errors.Join(errGetComment, err)
|
||||
var items []*youtube.Comment
|
||||
pageToken := ""
|
||||
for c.MaxResults > 0 {
|
||||
call = call.MaxResults(min(c.MaxResults, pkg.PerPage))
|
||||
c.MaxResults -= pkg.PerPage
|
||||
if pageToken != "" {
|
||||
call = call.PageToken(pageToken)
|
||||
}
|
||||
|
||||
res, err := call.Do()
|
||||
if err != nil {
|
||||
return items, errors.Join(errGetComment, err)
|
||||
}
|
||||
|
||||
items = append(items, res.Items...)
|
||||
pageToken = res.NextPageToken
|
||||
if pageToken == "" || len(res.Items) == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return res.Items, nil
|
||||
return items, nil
|
||||
}
|
||||
|
||||
func (c *comment) List(
|
||||
parts []string, output string, jpath string, writer io.Writer,
|
||||
) error {
|
||||
comments, err := c.Get(parts)
|
||||
if err != nil {
|
||||
if err != nil && comments == nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -114,7 +125,7 @@ func (c *comment) List(
|
||||
)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *comment) Insert(output string, jpath string, writer io.Writer) error {
|
||||
|
||||
@@ -33,15 +33,15 @@ type commentThread struct {
|
||||
VideoId string `yaml:"video_id" json:"video_id"`
|
||||
}
|
||||
|
||||
type CommentThread interface {
|
||||
Get([]string) ([]*youtube.CommentThread, error)
|
||||
type CommentThread[T any] interface {
|
||||
Get([]string) ([]*T, error)
|
||||
List([]string, string, string, io.Writer) error
|
||||
Insert(output string, s string, writer io.Writer) error
|
||||
}
|
||||
|
||||
type Option func(*commentThread)
|
||||
|
||||
func NewCommentThread(opts ...Option) CommentThread {
|
||||
func NewCommentThread(opts ...Option) CommentThread[youtube.CommentThread] {
|
||||
c := &commentThread{}
|
||||
|
||||
for _, opt := range opts {
|
||||
@@ -53,54 +53,60 @@ func NewCommentThread(opts ...Option) CommentThread {
|
||||
|
||||
func (c *commentThread) Get(parts []string) ([]*youtube.CommentThread, error) {
|
||||
call := service.CommentThreads.List(parts)
|
||||
|
||||
if len(c.IDs) > 0 {
|
||||
call = call.Id(c.IDs...)
|
||||
}
|
||||
|
||||
if c.AllThreadsRelatedToChannelId != "" {
|
||||
call = call.AllThreadsRelatedToChannelId(c.AllThreadsRelatedToChannelId)
|
||||
}
|
||||
|
||||
if c.ChannelId != "" {
|
||||
call = call.ChannelId(c.ChannelId)
|
||||
}
|
||||
|
||||
call = call.MaxResults(c.MaxResults)
|
||||
|
||||
if c.ModerationStatus != "" {
|
||||
call = call.ModerationStatus(c.ModerationStatus)
|
||||
}
|
||||
|
||||
if c.Order != "" {
|
||||
call = call.Order(c.Order)
|
||||
}
|
||||
|
||||
if c.SearchTerms != "" {
|
||||
call = call.SearchTerms(c.SearchTerms)
|
||||
}
|
||||
|
||||
if c.TextFormat != "" {
|
||||
call = call.TextFormat(c.TextFormat)
|
||||
}
|
||||
|
||||
if c.VideoId != "" {
|
||||
call = call.VideoId(c.VideoId)
|
||||
}
|
||||
|
||||
res, err := call.Do()
|
||||
if err != nil {
|
||||
return nil, errors.Join(errGetCommentThread, err)
|
||||
var items []*youtube.CommentThread
|
||||
pageToken := ""
|
||||
for c.MaxResults > 0 {
|
||||
call = call.MaxResults(min(c.MaxResults, pkg.PerPage))
|
||||
c.MaxResults -= pkg.PerPage
|
||||
if pageToken != "" {
|
||||
call = call.PageToken(pageToken)
|
||||
}
|
||||
|
||||
res, err := call.Do()
|
||||
if err != nil {
|
||||
return items, errors.Join(errGetCommentThread, err)
|
||||
}
|
||||
|
||||
items = append(items, res.Items...)
|
||||
pageToken = res.NextPageToken
|
||||
if pageToken == "" || len(res.Items) == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return res.Items, nil
|
||||
return items, nil
|
||||
}
|
||||
|
||||
func (c *commentThread) List(
|
||||
parts []string, output string, jpath string, writer io.Writer,
|
||||
) error {
|
||||
commentThreads, err := c.Get(parts)
|
||||
if err != nil {
|
||||
if err != nil && commentThreads == nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -126,7 +132,7 @@ func (c *commentThread) List(
|
||||
)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *commentThread) Insert(
|
||||
|
||||
@@ -20,14 +20,14 @@ type i18nLanguage struct {
|
||||
Hl string `yaml:"hl" json:"hl"`
|
||||
}
|
||||
|
||||
type I18nLanguage interface {
|
||||
Get([]string) ([]*youtube.I18nLanguage, error)
|
||||
type I18nLanguage[T youtube.I18nLanguage] interface {
|
||||
Get([]string) ([]*T, error)
|
||||
List([]string, string, string, io.Writer) error
|
||||
}
|
||||
|
||||
type Option func(*i18nLanguage)
|
||||
|
||||
func NewI18nLanguage(opts ...Option) I18nLanguage {
|
||||
func NewI18nLanguage(opts ...Option) I18nLanguage[youtube.I18nLanguage] {
|
||||
i := &i18nLanguage{}
|
||||
|
||||
for _, opt := range opts {
|
||||
@@ -37,7 +37,9 @@ func NewI18nLanguage(opts ...Option) I18nLanguage {
|
||||
return i
|
||||
}
|
||||
|
||||
func (i *i18nLanguage) Get(parts []string) ([]*youtube.I18nLanguage, error) {
|
||||
func (i *i18nLanguage) Get(parts []string) (
|
||||
[]*youtube.I18nLanguage, error,
|
||||
) {
|
||||
call := service.I18nLanguages.List(parts)
|
||||
if i.Hl != "" {
|
||||
call = call.Hl(i.Hl)
|
||||
|
||||
@@ -20,14 +20,14 @@ type i18nRegion struct {
|
||||
Hl string `yaml:"hl" json:"hl"`
|
||||
}
|
||||
|
||||
type I18nRegion interface {
|
||||
Get([]string) ([]*youtube.I18nRegion, error)
|
||||
type I18nRegion[T any] interface {
|
||||
Get([]string) ([]*T, error)
|
||||
List([]string, string, string, io.Writer) error
|
||||
}
|
||||
|
||||
type Option func(*i18nRegion)
|
||||
|
||||
func NewI18nRegion(opts ...Option) I18nRegion {
|
||||
func NewI18nRegion(opts ...Option) I18nRegion[youtube.I18nRegion] {
|
||||
i := &i18nRegion{}
|
||||
|
||||
for _, opt := range opts {
|
||||
|
||||
@@ -4,6 +4,10 @@ import (
|
||||
"io"
|
||||
)
|
||||
|
||||
type Getter[T any] interface {
|
||||
Get([]string) ([]*T, error)
|
||||
}
|
||||
|
||||
type Lister interface {
|
||||
List([]string, string, string, io.Writer) error
|
||||
}
|
||||
|
||||
+25
-10
@@ -24,14 +24,14 @@ type member struct {
|
||||
Mode string `yaml:"mode" json:"mode"`
|
||||
}
|
||||
|
||||
type Member interface {
|
||||
type Member[T any] interface {
|
||||
List([]string, string, string, io.Writer) error
|
||||
Get([]string) ([]*youtube.Member, error)
|
||||
Get([]string) ([]*T, error)
|
||||
}
|
||||
|
||||
type Option func(*member)
|
||||
|
||||
func NewMember(opts ...Option) Member {
|
||||
func NewMember(opts ...Option) Member[youtube.Member] {
|
||||
m := &member{}
|
||||
|
||||
for _, opt := range opts {
|
||||
@@ -49,24 +49,39 @@ func (m *member) Get(parts []string) ([]*youtube.Member, error) {
|
||||
if m.HasAccessToLevel != "" {
|
||||
call = call.HasAccessToLevel(m.HasAccessToLevel)
|
||||
}
|
||||
call = call.MaxResults(m.MaxResults)
|
||||
if m.Mode != "" {
|
||||
call = call.Mode(m.Mode)
|
||||
}
|
||||
|
||||
res, err := call.Do()
|
||||
if err != nil {
|
||||
return nil, errors.Join(errGetMember, err)
|
||||
var items []*youtube.Member
|
||||
pageToken := ""
|
||||
for m.MaxResults > 0 {
|
||||
call = call.MaxResults(min(m.MaxResults, pkg.PerPage))
|
||||
m.MaxResults -= pkg.PerPage
|
||||
if pageToken != "" {
|
||||
call = call.PageToken(pageToken)
|
||||
}
|
||||
|
||||
res, err := call.Do()
|
||||
if err != nil {
|
||||
return items, errors.Join(errGetMember, err)
|
||||
}
|
||||
|
||||
items = append(items, res.Items...)
|
||||
pageToken = res.NextPageToken
|
||||
if pageToken == "" || len(res.Items) == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return res.Items, nil
|
||||
return items, nil
|
||||
}
|
||||
|
||||
func (m *member) List(
|
||||
parts []string, output string, jpath string, writer io.Writer,
|
||||
) error {
|
||||
members, err := m.Get(parts)
|
||||
if err != nil {
|
||||
if err != nil && members == nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -91,7 +106,7 @@ func (m *member) List(
|
||||
)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
func WithMemberChannelId(channelId string) Option {
|
||||
|
||||
@@ -18,14 +18,14 @@ var (
|
||||
|
||||
type membershipsLevel struct{}
|
||||
|
||||
type MembershipsLevel interface {
|
||||
type MembershipsLevel[T any] interface {
|
||||
List([]string, string, string, io.Writer) error
|
||||
Get([]string) ([]*youtube.MembershipsLevel, error)
|
||||
Get([]string) ([]*T, error)
|
||||
}
|
||||
|
||||
type Option func(*membershipsLevel)
|
||||
|
||||
func NewMembershipsLevel(opts ...Option) MembershipsLevel {
|
||||
func NewMembershipsLevel(opts ...Option) MembershipsLevel[youtube.MembershipsLevel] {
|
||||
m := &membershipsLevel{}
|
||||
|
||||
for _, opt := range opts {
|
||||
|
||||
+25
-10
@@ -37,17 +37,17 @@ type playlist struct {
|
||||
OnBehalfOfContentOwnerChannel string `yaml:"on_behalf_of_content_owner_channel" json:"on_behalf_of_content_owner_channel"`
|
||||
}
|
||||
|
||||
type Playlist interface {
|
||||
type Playlist[T any] interface {
|
||||
List([]string, string, string, io.Writer) error
|
||||
Insert(string, string, io.Writer) error
|
||||
Update(string, string, io.Writer) error
|
||||
Delete(io.Writer) error
|
||||
Get([]string) ([]*youtube.Playlist, error)
|
||||
Get([]string) ([]*T, error)
|
||||
}
|
||||
|
||||
type Option func(*playlist)
|
||||
|
||||
func NewPlaylist(opts ...Option) Playlist {
|
||||
func NewPlaylist(opts ...Option) Playlist[youtube.Playlist] {
|
||||
p := &playlist{}
|
||||
|
||||
for _, opt := range opts {
|
||||
@@ -69,7 +69,6 @@ func (p *playlist) Get(parts []string) ([]*youtube.Playlist, error) {
|
||||
if p.Mine != nil {
|
||||
call = call.Mine(*p.Mine)
|
||||
}
|
||||
call = call.MaxResults(p.MaxResults)
|
||||
if p.OnBehalfOfContentOwner != "" {
|
||||
call = call.OnBehalfOfContentOwner(p.OnBehalfOfContentOwner)
|
||||
}
|
||||
@@ -77,19 +76,35 @@ func (p *playlist) Get(parts []string) ([]*youtube.Playlist, error) {
|
||||
call = call.OnBehalfOfContentOwnerChannel(p.OnBehalfOfContentOwnerChannel)
|
||||
}
|
||||
|
||||
res, err := call.Do()
|
||||
if err != nil {
|
||||
return nil, errors.Join(errGetPlaylist, err)
|
||||
var items []*youtube.Playlist
|
||||
pageToken := ""
|
||||
for p.MaxResults > 0 {
|
||||
call = call.MaxResults(min(p.MaxResults, pkg.PerPage))
|
||||
p.MaxResults -= pkg.PerPage
|
||||
if pageToken != "" {
|
||||
call = call.PageToken(pageToken)
|
||||
}
|
||||
|
||||
res, err := call.Do()
|
||||
if err != nil {
|
||||
return items, errors.Join(errGetPlaylist, err)
|
||||
}
|
||||
|
||||
items = append(items, res.Items...)
|
||||
pageToken = res.NextPageToken
|
||||
if pageToken == "" || len(res.Items) == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return res.Items, nil
|
||||
return items, nil
|
||||
}
|
||||
|
||||
func (p *playlist) List(
|
||||
parts []string, output string, jpath string, writer io.Writer,
|
||||
) error {
|
||||
playlists, err := p.Get(parts)
|
||||
if err != nil {
|
||||
if err != nil && playlists == nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -109,7 +124,7 @@ func (p *playlist) List(
|
||||
tb.AppendRow(table.Row{pl.Id, pl.Snippet.ChannelId, pl.Snippet.Title})
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
func (p *playlist) Insert(output string, jpath string, writer io.Writer) error {
|
||||
|
||||
@@ -36,8 +36,8 @@ type playlistImage struct {
|
||||
OnBehalfOfContentOwnerChannel string `yaml:"on_behalf_of_content_owner_channel" json:"on_behalf_of_content_owner_channel"`
|
||||
}
|
||||
|
||||
type PlaylistImage interface {
|
||||
Get([]string) ([]*youtube.PlaylistImage, error)
|
||||
type PlaylistImage[T any] interface {
|
||||
Get([]string) ([]*T, error)
|
||||
List([]string, string, string, io.Writer) error
|
||||
Insert(string, string, io.Writer) error
|
||||
Update(string, string, io.Writer) error
|
||||
@@ -46,7 +46,7 @@ type PlaylistImage interface {
|
||||
|
||||
type Option func(*playlistImage)
|
||||
|
||||
func NewPlaylistImage(opts ...Option) PlaylistImage {
|
||||
func NewPlaylistImage(opts ...Option) PlaylistImage[youtube.PlaylistImage] {
|
||||
pi := &playlistImage{}
|
||||
for _, opt := range opts {
|
||||
opt(pi)
|
||||
@@ -57,7 +57,6 @@ func NewPlaylistImage(opts ...Option) PlaylistImage {
|
||||
func (pi *playlistImage) Get(parts []string) ([]*youtube.PlaylistImage, error) {
|
||||
call := service.PlaylistImages.List()
|
||||
call = call.Part(parts...)
|
||||
|
||||
if pi.Parent != "" {
|
||||
call = call.Parent(pi.Parent)
|
||||
}
|
||||
@@ -67,21 +66,36 @@ func (pi *playlistImage) Get(parts []string) ([]*youtube.PlaylistImage, error) {
|
||||
if pi.OnBehalfOfContentOwnerChannel != "" {
|
||||
call = call.OnBehalfOfContentOwnerChannel(pi.OnBehalfOfContentOwnerChannel)
|
||||
}
|
||||
call = call.MaxResults(pi.MaxResults)
|
||||
|
||||
res, err := call.Do()
|
||||
if err != nil {
|
||||
return nil, errors.Join(errGetPlaylistImage, err)
|
||||
var items []*youtube.PlaylistImage
|
||||
pageToken := ""
|
||||
for pi.MaxResults > 0 {
|
||||
call = call.MaxResults(min(pi.MaxResults, pkg.PerPage))
|
||||
pi.MaxResults -= pkg.PerPage
|
||||
if pageToken != "" {
|
||||
call = call.PageToken(pageToken)
|
||||
}
|
||||
|
||||
res, err := call.Do()
|
||||
if err != nil {
|
||||
return items, errors.Join(errGetPlaylistImage, err)
|
||||
}
|
||||
|
||||
items = append(items, res.Items...)
|
||||
pageToken = res.NextPageToken
|
||||
if pageToken == "" || len(res.Items) == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return res.Items, nil
|
||||
return items, nil
|
||||
}
|
||||
|
||||
func (pi *playlistImage) List(
|
||||
parts []string, output string, jpath string, writer io.Writer,
|
||||
) error {
|
||||
playlistImages, err := pi.Get(parts)
|
||||
if err != nil {
|
||||
if err != nil && playlistImages == nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -103,7 +117,7 @@ func (pi *playlistImage) List(
|
||||
)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
func (pi *playlistImage) Insert(
|
||||
|
||||
@@ -38,17 +38,17 @@ type playlistItem struct {
|
||||
OnBehalfOfContentOwner string `yaml:"on_behalf_of_content_owner" json:"on_behalf_of_content_owner"`
|
||||
}
|
||||
|
||||
type PlaylistItem interface {
|
||||
type PlaylistItem[T any] interface {
|
||||
List([]string, string, string, io.Writer) error
|
||||
Insert(string, string, io.Writer) error
|
||||
Update(string, string, io.Writer) error
|
||||
Delete(io.Writer) error
|
||||
Get([]string) ([]*youtube.PlaylistItem, error)
|
||||
Get([]string) ([]*T, error)
|
||||
}
|
||||
|
||||
type Option func(*playlistItem)
|
||||
|
||||
func NewPlaylistItem(opts ...Option) PlaylistItem {
|
||||
func NewPlaylistItem(opts ...Option) PlaylistItem[youtube.PlaylistItem] {
|
||||
p := &playlistItem{}
|
||||
|
||||
for _, opt := range opts {
|
||||
@@ -72,20 +72,36 @@ func (pi *playlistItem) Get(parts []string) ([]*youtube.PlaylistItem, error) {
|
||||
if pi.VideoId != "" {
|
||||
call = call.VideoId(pi.VideoId)
|
||||
}
|
||||
call = call.MaxResults(pi.MaxResults)
|
||||
res, err := call.Do()
|
||||
if err != nil {
|
||||
return nil, errors.Join(errGetPlaylistItem, err)
|
||||
|
||||
var items []*youtube.PlaylistItem
|
||||
pageToken := ""
|
||||
for pi.MaxResults > 0 {
|
||||
call = call.MaxResults(min(pi.MaxResults, pkg.PerPage))
|
||||
pi.MaxResults -= pkg.PerPage
|
||||
if pageToken != "" {
|
||||
call = call.PageToken(pageToken)
|
||||
}
|
||||
|
||||
res, err := call.Do()
|
||||
if err != nil {
|
||||
return items, errors.Join(errGetPlaylistItem, err)
|
||||
}
|
||||
|
||||
items = append(items, res.Items...)
|
||||
pageToken = res.NextPageToken
|
||||
if pageToken == "" || len(res.Items) == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return res.Items, nil
|
||||
return items, nil
|
||||
}
|
||||
|
||||
func (pi *playlistItem) List(
|
||||
parts []string, output string, jpath string, writer io.Writer,
|
||||
) error {
|
||||
playlistItems, err := pi.Get(parts)
|
||||
if err != nil {
|
||||
if err != nil && playlistItems == nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -118,7 +134,7 @@ func (pi *playlistItem) List(
|
||||
)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
func (pi *playlistItem) Insert(
|
||||
|
||||
+25
-38
@@ -49,14 +49,14 @@ type search struct {
|
||||
VideoType string `yaml:"video_type" json:"video_type"`
|
||||
}
|
||||
|
||||
type Search interface {
|
||||
Get([]string) ([]*youtube.SearchResult, error)
|
||||
type Search[T any] interface {
|
||||
Get([]string) ([]*T, error)
|
||||
List([]string, string, string, io.Writer) error
|
||||
}
|
||||
|
||||
type Option func(*search)
|
||||
|
||||
func NewSearch(opts ...Option) Search {
|
||||
func NewSearch(opts ...Option) Search[youtube.SearchResult] {
|
||||
s := &search{}
|
||||
|
||||
for _, opt := range opts {
|
||||
@@ -71,130 +71,117 @@ func (s *search) Get(parts []string) ([]*youtube.SearchResult, error) {
|
||||
if s.ChannelId != "" {
|
||||
call.ChannelId(s.ChannelId)
|
||||
}
|
||||
|
||||
if s.ChannelType != "" {
|
||||
call.ChannelType(s.ChannelType)
|
||||
}
|
||||
|
||||
if s.EventType != "" {
|
||||
call.EventType(s.EventType)
|
||||
}
|
||||
|
||||
if s.ForContentOwner != nil {
|
||||
call.ForContentOwner(*s.ForContentOwner)
|
||||
}
|
||||
|
||||
if s.ForDeveloper != nil {
|
||||
call.ForDeveloper(*s.ForDeveloper)
|
||||
}
|
||||
|
||||
if s.ForMine != nil {
|
||||
call.ForMine(*s.ForMine)
|
||||
}
|
||||
|
||||
if s.Location != "" {
|
||||
call.Location(s.Location)
|
||||
}
|
||||
|
||||
if s.LocationRadius != "" {
|
||||
call.LocationRadius(s.LocationRadius)
|
||||
}
|
||||
|
||||
call.MaxResults(s.MaxResults)
|
||||
|
||||
if s.OnBehalfOfContentOwner != "" {
|
||||
call.OnBehalfOfContentOwner(s.OnBehalfOfContentOwner)
|
||||
}
|
||||
|
||||
if s.Order != "" {
|
||||
call.Order(s.Order)
|
||||
}
|
||||
|
||||
if s.PublishedAfter != "" {
|
||||
call.PublishedAfter(s.PublishedAfter)
|
||||
}
|
||||
|
||||
if s.PublishedBefore != "" {
|
||||
call.PublishedBefore(s.PublishedBefore)
|
||||
}
|
||||
|
||||
if s.Q != "" {
|
||||
call.Q(s.Q)
|
||||
}
|
||||
|
||||
if s.RegionCode != "" {
|
||||
call.RegionCode(s.RegionCode)
|
||||
}
|
||||
|
||||
if s.RelevanceLanguage != "" {
|
||||
call.RelevanceLanguage(s.RelevanceLanguage)
|
||||
}
|
||||
|
||||
if s.SafeSearch != "" {
|
||||
call.SafeSearch(s.SafeSearch)
|
||||
}
|
||||
|
||||
if s.TopicId != "" {
|
||||
call.TopicId(s.TopicId)
|
||||
}
|
||||
|
||||
if len(s.Types) > 0 {
|
||||
call.Type(s.Types...)
|
||||
}
|
||||
|
||||
if s.VideoCaption != "" {
|
||||
call.VideoCaption(s.VideoCaption)
|
||||
}
|
||||
|
||||
if s.VideoCategoryId != "" {
|
||||
call.VideoCategoryId(s.VideoCategoryId)
|
||||
}
|
||||
|
||||
if s.VideoDefinition != "" {
|
||||
call.VideoDefinition(s.VideoDefinition)
|
||||
}
|
||||
|
||||
if s.VideoDimension != "" {
|
||||
call.VideoDimension(s.VideoDimension)
|
||||
}
|
||||
|
||||
if s.VideoDuration != "" {
|
||||
call.VideoDuration(s.VideoDuration)
|
||||
}
|
||||
|
||||
if s.VideoEmbeddable != "" {
|
||||
call.VideoEmbeddable(s.VideoEmbeddable)
|
||||
}
|
||||
|
||||
if s.VideoLicense != "" {
|
||||
call.VideoLicense(s.VideoLicense)
|
||||
}
|
||||
|
||||
if s.VideoPaidProductPlacement != "" {
|
||||
call.VideoPaidProductPlacement(s.VideoPaidProductPlacement)
|
||||
}
|
||||
|
||||
if s.VideoSyndicated != "" {
|
||||
call.VideoSyndicated(s.VideoSyndicated)
|
||||
}
|
||||
|
||||
if s.VideoType != "" {
|
||||
call.VideoType(s.VideoType)
|
||||
}
|
||||
|
||||
res, err := call.Do()
|
||||
if err != nil {
|
||||
return nil, errors.Join(errGetSearch, err)
|
||||
var items []*youtube.SearchResult
|
||||
pageToken := ""
|
||||
for s.MaxResults > 0 {
|
||||
call = call.MaxResults(min(s.MaxResults, pkg.PerPage))
|
||||
s.MaxResults -= pkg.PerPage
|
||||
if pageToken != "" {
|
||||
call = call.PageToken(pageToken)
|
||||
}
|
||||
|
||||
res, err := call.Do()
|
||||
if err != nil {
|
||||
return items, errors.Join(errGetSearch, err)
|
||||
}
|
||||
|
||||
items = append(items, res.Items...)
|
||||
pageToken = res.NextPageToken
|
||||
if pageToken == "" || len(res.Items) == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return res.Items, nil
|
||||
return items, nil
|
||||
}
|
||||
|
||||
func (s *search) List(
|
||||
parts []string, output string, jpath string, writer io.Writer,
|
||||
) error {
|
||||
results, err := s.Get(parts)
|
||||
if err != nil {
|
||||
if err != nil && results == nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -225,7 +212,7 @@ func (s *search) List(
|
||||
)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
func WithChannelId(channelId string) Option {
|
||||
|
||||
@@ -36,8 +36,8 @@ type subscription struct {
|
||||
Title string `yaml:"title" json:"title"`
|
||||
}
|
||||
|
||||
type Subscription interface {
|
||||
Get([]string) ([]*youtube.Subscription, error)
|
||||
type Subscription[T any] interface {
|
||||
Get([]string) ([]*T, error)
|
||||
List([]string, string, string, io.Writer) error
|
||||
Insert(string, string, io.Writer) error
|
||||
Delete(io.Writer) error
|
||||
@@ -45,7 +45,7 @@ type Subscription interface {
|
||||
|
||||
type Option func(*subscription)
|
||||
|
||||
func NewSubscription(opts ...Option) Subscription {
|
||||
func NewSubscription(opts ...Option) Subscription[youtube.Subscription] {
|
||||
s := &subscription{}
|
||||
|
||||
for _, opt := range opts {
|
||||
@@ -66,8 +66,6 @@ func (s *subscription) Get(parts []string) ([]*youtube.Subscription, error) {
|
||||
if s.ForChannelId != "" {
|
||||
call = call.ForChannelId(s.ForChannelId)
|
||||
}
|
||||
call = call.MaxResults(s.MaxResults)
|
||||
|
||||
if s.Mine != nil {
|
||||
call = call.Mine(*s.Mine)
|
||||
}
|
||||
@@ -77,7 +75,6 @@ func (s *subscription) Get(parts []string) ([]*youtube.Subscription, error) {
|
||||
if s.MySubscribers != nil {
|
||||
call = call.MySubscribers(*s.MySubscribers)
|
||||
}
|
||||
|
||||
if s.OnBehalfOfContentOwner != "" {
|
||||
call = call.OnBehalfOfContentOwner(s.OnBehalfOfContentOwner)
|
||||
}
|
||||
@@ -88,20 +85,36 @@ func (s *subscription) Get(parts []string) ([]*youtube.Subscription, error) {
|
||||
call = call.Order(s.Order)
|
||||
}
|
||||
|
||||
res, err := call.Do()
|
||||
if err != nil {
|
||||
return nil, errors.Join(errGetSubscription, err)
|
||||
var items []*youtube.Subscription
|
||||
pageToken := ""
|
||||
for s.MaxResults > 0 {
|
||||
call = call.MaxResults(min(s.MaxResults, pkg.PerPage))
|
||||
s.MaxResults -= pkg.PerPage
|
||||
if pageToken != "" {
|
||||
call = call.PageToken(pageToken)
|
||||
}
|
||||
|
||||
res, err := call.Do()
|
||||
if err != nil {
|
||||
return items, errors.Join(errGetSubscription, err)
|
||||
}
|
||||
|
||||
items = append(items, res.Items...)
|
||||
pageToken = res.NextPageToken
|
||||
if pageToken == "" || len(res.Items) == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return res.Items, nil
|
||||
return items, nil
|
||||
}
|
||||
|
||||
func (s *subscription) List(
|
||||
parts []string, output string, jpath string, writer io.Writer,
|
||||
) error {
|
||||
subscriptions, err := s.Get(parts)
|
||||
if err != nil {
|
||||
return errors.Join(errGetSubscription, err)
|
||||
if err != nil && subscriptions == nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch output {
|
||||
@@ -133,7 +146,7 @@ func (s *subscription) List(
|
||||
)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *subscription) Insert(
|
||||
|
||||
@@ -22,14 +22,14 @@ type superChatEvent struct {
|
||||
MaxResults int64 `yaml:"max_results" json:"max_results"`
|
||||
}
|
||||
|
||||
type SuperChatEvent interface {
|
||||
Get([]string) ([]*youtube.SuperChatEvent, error)
|
||||
type SuperChatEvent[T any] interface {
|
||||
Get([]string) ([]*T, error)
|
||||
List([]string, string, string, io.Writer) error
|
||||
}
|
||||
|
||||
type Option func(*superChatEvent)
|
||||
|
||||
func NewSuperChatEvent(opts ...Option) SuperChatEvent {
|
||||
func NewSuperChatEvent(opts ...Option) SuperChatEvent[youtube.SuperChatEvent] {
|
||||
s := &superChatEvent{}
|
||||
|
||||
for _, opt := range opts {
|
||||
@@ -44,22 +44,37 @@ func (s *superChatEvent) Get(parts []string) ([]*youtube.SuperChatEvent, error)
|
||||
if s.Hl != "" {
|
||||
call = call.Hl(s.Hl)
|
||||
}
|
||||
call = call.MaxResults(s.MaxResults)
|
||||
|
||||
res, err := call.Do()
|
||||
if err != nil {
|
||||
return nil, errors.Join(errGetSuperChatEvent, err)
|
||||
var items []*youtube.SuperChatEvent
|
||||
pageToken := ""
|
||||
for s.MaxResults > 0 {
|
||||
call = call.MaxResults(min(s.MaxResults, pkg.PerPage))
|
||||
s.MaxResults -= pkg.PerPage
|
||||
if pageToken != "" {
|
||||
call = call.PageToken(pageToken)
|
||||
}
|
||||
|
||||
res, err := call.Do()
|
||||
if err != nil {
|
||||
return items, errors.Join(errGetSuperChatEvent, err)
|
||||
}
|
||||
|
||||
items = append(items, res.Items...)
|
||||
pageToken = res.NextPageToken
|
||||
if pageToken == "" || len(res.Items) == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return res.Items, nil
|
||||
return items, nil
|
||||
}
|
||||
|
||||
func (s *superChatEvent) List(
|
||||
parts []string, output string, jpath string, writer io.Writer,
|
||||
) error {
|
||||
events, err := s.Get(parts)
|
||||
if err != nil {
|
||||
return errors.Join(errGetSuperChatEvent, err)
|
||||
if err != nil && events == nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch output {
|
||||
@@ -83,7 +98,7 @@ func (s *superChatEvent) List(
|
||||
)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
func WithHl(hl string) Option {
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ import (
|
||||
|
||||
const (
|
||||
PartsUsage = "Comma separated parts"
|
||||
MRUsage = "The maximum number of items that should be returned"
|
||||
MRUsage = "The maximum number of items that should be returned, 0 for no limit"
|
||||
TableUsage = "json, yaml, or table"
|
||||
SilentUsage = "json, yaml, or silent"
|
||||
JPUsage = "JSONPath expression to filter the output"
|
||||
|
||||
+25
-10
@@ -64,7 +64,7 @@ type video struct {
|
||||
OnBehalfOfContentOwnerChannel string `yaml:"on_behalf_of_content_owner_channel" json:"on_behalf_of_content_owner_channel"`
|
||||
}
|
||||
|
||||
type Video interface {
|
||||
type Video[T any] interface {
|
||||
List([]string, string, string, io.Writer) error
|
||||
Insert(string, string, io.Writer) error
|
||||
Update(string, string, io.Writer) error
|
||||
@@ -72,12 +72,12 @@ type Video interface {
|
||||
GetRating(string, string, io.Writer) error
|
||||
Delete(io.Writer) error
|
||||
ReportAbuse(io.Writer) error
|
||||
Get([]string) ([]*youtube.Video, error)
|
||||
Get([]string) ([]*T, error)
|
||||
}
|
||||
|
||||
type Option func(*video)
|
||||
|
||||
func NewVideo(opts ...Option) Video {
|
||||
func NewVideo(opts ...Option) Video[youtube.Video] {
|
||||
v := &video{}
|
||||
|
||||
for _, opt := range opts {
|
||||
@@ -119,21 +119,36 @@ func (v *video) Get(parts []string) ([]*youtube.Video, error) {
|
||||
if v.OnBehalfOfContentOwner != "" {
|
||||
call = call.OnBehalfOfContentOwner(v.OnBehalfOfContentOwner)
|
||||
}
|
||||
call = call.MaxResults(v.MaxResults)
|
||||
|
||||
res, err := call.Do()
|
||||
if err != nil {
|
||||
return nil, errors.Join(errGetVideo, err)
|
||||
var items []*youtube.Video
|
||||
pageToken := ""
|
||||
for v.MaxResults > 0 {
|
||||
call = call.MaxResults(min(v.MaxResults, pkg.PerPage))
|
||||
v.MaxResults -= pkg.PerPage
|
||||
if pageToken != "" {
|
||||
call = call.PageToken(pageToken)
|
||||
}
|
||||
|
||||
res, err := call.Do()
|
||||
if err != nil {
|
||||
return items, errors.Join(errGetVideo, err)
|
||||
}
|
||||
|
||||
items = append(items, res.Items...)
|
||||
pageToken = res.NextPageToken
|
||||
if pageToken == "" || len(res.Items) == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return res.Items, nil
|
||||
return items, nil
|
||||
}
|
||||
|
||||
func (v *video) List(
|
||||
parts []string, output string, jpath string, writer io.Writer,
|
||||
) error {
|
||||
videos, err := v.Get(parts)
|
||||
if err != nil {
|
||||
if err != nil && videos == nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -159,7 +174,7 @@ func (v *video) List(
|
||||
)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
func (v *video) Insert(output string, jpath string, writer io.Writer) error {
|
||||
|
||||
@@ -20,14 +20,14 @@ type videoAbuseReportReason struct {
|
||||
Hl string `yaml:"hl" json:"hl"`
|
||||
}
|
||||
|
||||
type VideoAbuseReportReason interface {
|
||||
Get([]string) ([]*youtube.VideoAbuseReportReason, error)
|
||||
type VideoAbuseReportReason[T any] interface {
|
||||
Get([]string) ([]*T, error)
|
||||
List([]string, string, string, io.Writer) error
|
||||
}
|
||||
|
||||
type Option func(*videoAbuseReportReason)
|
||||
|
||||
func NewVideoAbuseReportReason(opt ...Option) VideoAbuseReportReason {
|
||||
func NewVideoAbuseReportReason(opt ...Option) VideoAbuseReportReason[youtube.VideoAbuseReportReason] {
|
||||
va := &videoAbuseReportReason{}
|
||||
for _, o := range opt {
|
||||
o(va)
|
||||
|
||||
@@ -22,14 +22,14 @@ type videoCategory struct {
|
||||
RegionCode string `yaml:"region_code" json:"region_code"`
|
||||
}
|
||||
|
||||
type VideoCategory interface {
|
||||
Get([]string) ([]*youtube.VideoCategory, error)
|
||||
type VideoCategory[T any] interface {
|
||||
Get([]string) ([]*T, error)
|
||||
List([]string, string, string, io.Writer) error
|
||||
}
|
||||
|
||||
type Option func(*videoCategory)
|
||||
|
||||
func NewVideoCategory(opt ...Option) VideoCategory {
|
||||
func NewVideoCategory(opt ...Option) VideoCategory[youtube.VideoCategory] {
|
||||
vc := &videoCategory{}
|
||||
for _, o := range opt {
|
||||
o(vc)
|
||||
|
||||
Reference in new issue
Block a user