-
Notifications
You must be signed in to change notification settings - Fork 0
/
search.go
136 lines (113 loc) · 3.18 KB
/
search.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
132
133
134
135
136
package gotube
import (
"context"
"encoding/json"
"fmt"
"google.golang.org/api/option"
"google.golang.org/api/youtube/v3"
"log"
)
// SearchOptions is a struct with the search option information
type SearchOptions struct {
Query string
Limit int64
ApiKey string
}
type SearchResult struct {
Channels []*Channel
Videos []*Video
Playlists []*Playlist
}
// Search è una funzione che data una query e un limit effettua una ricerca e torna una slice di video info
func Search(opts SearchOptions) (results *SearchResult, err error) {
var sr SearchResult
// Search on youtube
items, err := searchYoutube(opts)
if err != nil {
panic(err)
}
// Iterate through each item and add it to the videos list.
for _, item := range items {
switch item.Id.Kind {
case "youtube#video":
v, err := searchParseVideo(item)
if err != nil {
return nil, err
}
sr.Videos = append(sr.Videos, v)
case "youtube#channel":
c, err := searchParseChannel(item)
if err != nil {
return nil, err
}
sr.Channels = append(sr.Channels, c)
case "youtube#playlist":
p, err := searchParsePlaylist(item)
if err != nil {
return nil, err
}
sr.Playlists = append(sr.Playlists, p)
}
}
return &sr, nil
}
// searchYoutube is a utility function that search on youtube and return a slice of youtube.SearchResult
func searchYoutube(opts SearchOptions) ([]*youtube.SearchResult, error) {
ctx := context.Background()
service, err := youtube.NewService(ctx, option.WithAPIKey(opts.ApiKey))
if err != nil {
log.Fatalf("Error creating new YouTube client: %v", err)
}
// Make the API call to YouTube.
call := service.Search.List([]string{"id", "snippet"}).
Q(opts.Query).
MaxResults(opts.Limit)
response, err := call.Do()
if err != nil {
return nil, err
}
return response.Items, nil
}
// searchParseVideo is a utility function that parse video search results
func searchParseVideo(item *youtube.SearchResult) (*Video, error) {
var v Video
var c Channel
v.Id = item.Id.VideoId
v.Title = item.Snippet.Title
v.Description = item.Snippet.Description
v.PublishedAt = item.Snippet.PublishedAt
v.Thumbnails = Thumbnails{*item.Snippet.Thumbnails}
// Parse channel
c.Id = item.Snippet.ChannelId
c.Title = item.Snippet.ChannelTitle
v.Channel = &c
return &v, nil
}
// searchParseChannel is a utility function that parse channel search results
func searchParseChannel(item *youtube.SearchResult) (*Channel, error) {
var c Channel
c.Id = item.Snippet.ChannelId
c.Title = item.Snippet.ChannelTitle
c.Description = item.Snippet.Description
c.Thumbnails = Thumbnails{*item.Snippet.Thumbnails}
data, err := json.Marshal(c)
if err != nil {
return nil, err
}
fmt.Println("Channel:", string(data))
return &c, nil
}
// searchParsePlaylist is a utility function that parse playlist search results
func searchParsePlaylist(item *youtube.SearchResult) (*Playlist, error) {
var p Playlist
var c Channel
p.Id = item.Snippet.ChannelId
p.Title = item.Snippet.ChannelTitle
p.Description = item.Snippet.Description
p.Thumbnails = Thumbnails{*item.Snippet.Thumbnails}
// Parse channel
c.Id = item.Snippet.ChannelId
c.Title = item.Snippet.ChannelTitle
p.Channel = &c
return &p, nil
}