-
Notifications
You must be signed in to change notification settings - Fork 0
/
service.go
131 lines (108 loc) · 3.13 KB
/
service.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package gotube
import (
"fmt"
"sync"
"github.com/aracki/gotube/model"
"google.golang.org/api/youtube/v3"
)
const (
snippetContentDetailsStatistics = "snippet,contentDetails,statistics"
snippetContentDetails = "snippet,contentDetails"
)
type Youtube struct {
Service *youtube.Service
}
// The getChannelInfo uses forUsername
// to get info (id, tittle, totalViews and description)
func (yt Youtube) ChannelInfo(forUsername string) (string, error) {
call := yt.Service.Channels.List(snippetContentDetailsStatistics)
call = call.ForUsername(forUsername)
response, err := call.Do()
if err != nil {
return "", err
}
var info string
info = fmt.Sprintf("This channel's ID is %s. Its title is '%s', "+
"and it has %d views. \n",
response.Items[0].Id,
response.Items[0].Snippet.Title,
response.Items[0].Statistics.ViewCount)
info += fmt.Sprintf(response.Items[0].Snippet.Description)
return info, nil
}
// Gets all playlists of current user - maxResult is set to 50 (default is 5)
// returns array of all playlists (id, name, count)
func (yt Youtube) GetAllPlaylists() ([]model.Playlist, error) {
// get all playlists
call := yt.Service.Playlists.List(snippetContentDetails)
call = call.MaxResults(50).Mine(true)
response, err := call.Do()
if err != nil {
return nil, err
}
var pls []model.Playlist
for _, pl := range response.Items {
pls = append(pls, model.Playlist{
Id: pl.Id,
Title: pl.Snippet.Title,
VideosCount: int(pl.ContentDetails.ItemCount),
})
}
return pls, nil
}
// Gets all the videos of all playlists of mine
// Different goroutines are appending the same vds slice;
// WaitGroup waits for all goroutines to finish
func (yt Youtube) GetAllVideos() (vds []model.Video, err error) {
// get all playlists of mine
call := yt.Service.Playlists.List(snippetContentDetails)
call = call.MaxResults(50).Mine(true)
response, err := call.Do()
if err != nil {
return nil, err
}
var wg sync.WaitGroup
wg.Add(len(response.Items))
for _, pl := range response.Items {
go func(p *youtube.Playlist) {
v, _ := getAllVideosByPlaylist(yt.Service, p)
vds = append(vds, v...)
wg.Done()
}(pl)
}
wg.Wait()
return vds, nil
}
// Gets all the videos of specific youtube.Playlist
func getAllVideosByPlaylist(service *youtube.Service, pl *youtube.Playlist) ([]model.Video, error) {
var vds []model.Video
pageToken := ""
for {
call := service.PlaylistItems.List(snippetContentDetails)
call = call.PlaylistId(pl.Id).MaxResults(50)
response, err := call.PageToken(pageToken).Do()
if err != nil {
return nil, err
}
// move pageToken to another page
pageToken = response.NextPageToken
for _, item := range response.Items {
t := ""
if item.Snippet.Thumbnails != nil && item.Snippet.Thumbnails.Medium != nil {
t = item.Snippet.Thumbnails.Medium.Url
}
vds = append(vds, model.Video{
Title: item.Snippet.Title,
Description: item.Snippet.Description,
PublishedAt: item.Snippet.PublishedAt,
ResourceId: item.Snippet.ResourceId.VideoId,
Thumbnail: t,
})
}
// if there are no pages
if pageToken == "" {
break
}
}
return vds, nil
}