package youtube import ( "encoding/json" "net/http" "net/url" "io/ioutil" "strings" "errors" "log" "fmt" ) type Thumb struct { Url string Width int Height int } type Snip struct { PublishedAt string Title string Description string Thumbnails map[string]Thumb } type ContentD struct { Duration string } type Stats struct { LikeCount int64 `json:",string"` DislikeCount int64 `json:",string"` } type Stat struct { UploadStatus string PrivacyStatus string } type BrandingSetting struct { Image map[string]string } type Error struct { Code int Message string } type Item struct { Id string Snippet Snip ContentDetails ContentD Status Stat Statistics Stats BrandingSettings BrandingSetting } type YTResult struct { Items []Item Error *Error } var videoEndpoint string = "https://www.googleapis.com/youtube/v3/videos" var channelEndpoint string = "https://www.googleapis.com/youtube/v3/channels" var sem = make(chan byte, 10) // Make an HTTP Get Request to u func GetHTTPResource(u string) (*http.Response, error) { sem <- 1 // Prepare HTTP Client, Cookie and Request res, err := http.Get(u) if err != nil { log.Printf("[WARN] HTTP - Request to %s failed: %s", u, err) <- sem return nil, err } if res.StatusCode == http.StatusNotFound { log.Printf("[WARN] HTTP - Received 404 Not Found for: %s", u) <- sem return nil, nil } <- sem return res, nil } func GetVideos(parts []string, ids []string, key string) (*YTResult, error) { var ytVideo YTResult u, _ := url.Parse(videoEndpoint) query := u.Query() // Stringify arraysfmt p := strings.Join(parts, ",") i := strings.Join(ids, ",") // Set params in URL Query query.Set("part", p) query.Set("id", i) query.Set("key", key) u.RawQuery = query.Encode() res, err := GetHTTPResource(u.String()) if err != nil { return nil, err } defer res.Body.Close() body, err := ioutil.ReadAll(res.Body) if err != nil { return nil, err } jerr := json.Unmarshal(body, &ytVideo) if jerr != nil { return nil, jerr } return &ytVideo, nil } func GetChannel(parts []string, id string, key string) (*YTResult, error) { var ytRes YTResult u, _ := url.Parse(channelEndpoint) query := u.Query() // Stringify array p := strings.Join(parts, ",") // Set params in URL Query query.Set("part", p) query.Set("id", id) query.Set("key", key) u.RawQuery = query.Encode() res, err := GetHTTPResource(u.String()) if err != nil { return nil, err } defer res.Body.Close() body, err := ioutil.ReadAll(res.Body) if err != nil { return nil, err } jerr := json.Unmarshal(body, &ytRes) if jerr != nil { return nil, jerr } if ytRes.Error != nil { return nil, fmt.Errorf("Youtube Error: %+v: %s", ytRes.Error.Code, ytRes.Error.Message) } return &ytRes, nil } func GetChannelId(name string, key string) (string, error) { var ytRes YTResult u, _ := url.Parse(channelEndpoint) query := u.Query() // Set params in URL Query query.Set("part", "snippet") query.Set("forUsername", name) query.Set("key", key) u.RawQuery = query.Encode() res, err := GetHTTPResource(u.String()) if err != nil { return "", err } defer res.Body.Close() body, err := ioutil.ReadAll(res.Body) if err != nil { return "", err } jerr := json.Unmarshal(body, &ytRes) if jerr != nil { return "", jerr } if len(ytRes.Items) < 0 { return "", errors.New("API Error") } return ytRes.Items[0].Id, nil } func GetRatingAndVotesWithId(id string, key string) (float64, int64, string, Thumb) { ytres, err := GetVideos([]string {"statistics", "status", "snippet"}, []string {id}, key) if err != nil || len(ytres.Items) == 0 { return 0, 0, "private", Thumb{} } votes := ytres.Items[0].Statistics.LikeCount + ytres.Items[0].Statistics.DislikeCount var rating float64 if ytres.Items[0].Statistics.LikeCount != 0 { rating = (float64(ytres.Items[0].Statistics.LikeCount)/float64(votes))*10 } else { rating = 0 } status := ytres.Items[0].Status.PrivacyStatus if ytres.Items[0].Status.UploadStatus != "processed" { status = "private" } thumb, ok := ytres.Items[0].Snippet.Thumbnails["maxres"] if !ok { thumb, ok = ytres.Items[0].Snippet.Thumbnails["high"] } return rating, votes, status, thumb } func GetRatingAndVotesWithRes(ytres *YTResult) (float64, int64) { votes := ytres.Items[0].Statistics.LikeCount + ytres.Items[0].Statistics.DislikeCount var rating float64 if ytres.Items[0].Statistics.LikeCount != 0 { rating = (float64(ytres.Items[0].Statistics.LikeCount)/float64(votes))*10 } else { rating = 0 } return rating, votes }