WIP disclaimer
[yt-mango.git] / apijson / parsechannel.go
bloba821faf5b776786821bdc8cf11e2f7c7d85c393e
1 package apijson
3 import (
4 "github.com/valyala/fastjson"
5 "errors"
6 "strings"
7 "net/http"
8 "io/ioutil"
9 "fmt"
12 var MissingData = errors.New("missing data")
13 var ServerError = errors.New("server error")
15 func ParseChannelVideoURLs(res *http.Response) ([]string, error) {
16 if res.StatusCode != 200 {
17 return nil, fmt.Errorf("HTTP error: %s", res.Request.URL.String())
20 // Download response
21 defer res.Body.Close()
22 buf, err := ioutil.ReadAll(res.Body)
23 if err != nil { return nil, err }
25 // Parse JSON
26 var p fastjson.Parser
27 rootObj, err := p.ParseBytes(buf)
28 if err != nil { return nil, err }
30 // Root as array
31 root, err := rootObj.Array()
32 if err != nil { return nil, err }
34 // Find response container
35 var container *fastjson.Value
36 for _, item := range root {
37 if item.Exists("response") {
38 container = item
39 break
42 if container == nil { return nil, MissingData }
44 // Get error obj
45 errorExists := container.Exists(
46 "response",
47 "responseContext",
48 "errors",
49 "error",
51 if errorExists { return nil, ServerError }
53 // Get items from grid
54 itemsObj := container.Get(
55 "response",
56 "continuationContents",
57 "gridContinuation",
58 "items",
60 if itemsObj == nil { return nil, MissingData }
62 // Items as array
63 items, err := itemsObj.Array()
64 if err != nil { return nil, err }
66 urls := make([]string, 0)
68 // Enumerate
69 for _, item := range items {
70 // Find URL
71 urlObj := item.Get(
72 "gridVideoRenderer",
73 "navigationEndpoint",
74 "commandMetadata",
75 "webCommandMetadata",
76 "url",
78 if urlObj == nil { return nil, MissingData }
80 // URL as string
81 urlBytes, err := urlObj.StringBytes()
82 if err != nil { return nil, err }
83 url := string(urlBytes)
85 if strings.HasPrefix(url, "/watch?v") {
86 urls = append(urls, "https://www.youtube.com" + url)
89 return urls, nil