Added Genre

This commit is contained in:
Shiny Nematoda
2022-07-09 10:59:06 +00:00
parent 27d3562f01
commit 6a5f1d4b7a
7 changed files with 284 additions and 244 deletions
+96 -30
View File
@@ -1,11 +1,48 @@
package main
import (
"fmt"
"log"
"sync"
"github.com/tidwall/gjson"
)
func GetThumbnails(j gjson.Result) []Thumbnail {
t := []Thumbnail{}
wg := sync.WaitGroup{}
j.ForEach(
func(_, v gjson.Result) bool {
wg.Add(1)
go func() {
defer wg.Done()
u, err := ParseUrl(v.Get("url").String())
if err != nil {
log.Fatal(err)
}
t = append(t, Thumbnail{
Url: u,
Width: v.Get("width").Int(),
Height: v.Get("height").Int(),
})
}()
wg.Wait()
return true
},
)
return t
}
func TwoRowItemRenderer(t string, a gjson.Result) []Item {
r := []Item{}
@@ -13,7 +50,9 @@ func TwoRowItemRenderer(t string, a gjson.Result) []Item {
var id string
if t == "album" || t == "singles" {
id = "menu.menuRenderer.items.#(menuNavigationItemRenderer.text.runs.0.text == Shuffle play).menuNavigationItemRenderer.navigationEndpoint.watchPlaylistEndpoint.playlistId"
id = "menu.menuRenderer.items.#(menuNavigationItemRenderer" +
".text.runs.0.text == Shuffle play).menuNavigationItemRenderer" +
".navigationEndpoint.watchPlaylistEndpoint.playlistId"
} else {
id = "navigationEndpoint.browseEndpoint.browseId"
}
@@ -30,11 +69,18 @@ func TwoRowItemRenderer(t string, a gjson.Result) []Item {
go func() {
defer wg.Done()
gid := j.Get(id).String()
if len(gid) > 2 && gid[:2] == "VL" {
gid = gid[2:]
}
r = append(r, Item{
Id: j.Get(id).String(),
Title: RunsText(j.Get("title")),
Sub: RunsText(j.Get("subtitle")),
Thumbnails: GetThumbnails(j.Get("thumbnailRenderer.musicThumbnailRenderer.thumbnail.thumbnails")),
Id: gid,
Title: RunsText(j.Get("title")),
Sub: RunsText(j.Get("subtitle")),
Thumbnails: GetThumbnails(j.Get("thumbnailRenderer" +
".musicThumbnailRenderer.thumbnail.thumbnails")),
})
}()
@@ -48,25 +94,6 @@ func TwoRowItemRenderer(t string, a gjson.Result) []Item {
return r
}
func CarouselShelfRenderer(i gjson.Result) map[string]interface{} {
shelf := make(map[string]interface{})
shelf["title"] = RunsText(i.Get("header.musicCarouselShelfBasicHeaderRenderer.title"))
ct := i.Get("contents")
if ct.Get("#(musicTwoRowItemRenderer)").Exists() {
shelf["contents"] = TwoRowItemRenderer("", ct)
} else if ct.Get("#(musicResponsiveListItemRenderer)").Exists() {
shelf["contents"] = ResponsiveListItemRenderer(ct)
}
shelf["raw"] = ct.Value()
return shelf
}
func ResponsiveListItemRenderer(s gjson.Result) []Item {
r := []Item{}
@@ -82,14 +109,19 @@ func ResponsiveListItemRenderer(s gjson.Result) []Item {
defer wg.Done()
j := v.Get("musicResponsiveListItemRenderer")
flex := j.Get("flexColumns.#.musicResponsiveListItemFlexColumnRenderer.text.runs.0")
flex := j.Get("flexColumns.#.musicResponsiveListItemFlexColumnRenderer" +
".text.runs.0")
r = append(r, Item{
Id: j.Get("playlistItemData.videoId").String(),
Title: flex.Get("#(navigationEndpoint.watchEndpoint.videoId).text").String(),
SubId: flex.Get("#.navigationEndpoint.browseEndpoint").Get("#(browseId).browseId").String(),
Sub: flex.Get("#(navigationEndpoint.browseEndpoint.browseId).text").String(),
Thumbnails: GetThumbnails(j.Get("thumbnail.musicThumbnailRenderer.thumbnail.thumbnails")),
Id: j.Get("playlistItemData.videoId").String(),
Title: flex.Get("#(navigationEndpoint.watchEndpoint" +
".videoId).text").String(),
SubId: flex.Get("#.navigationEndpoint.browseEndpoint" +
".#(browseId).browseId").String(),
Sub: flex.Get("#(navigationEndpoint.browseEndpoint" +
".browseId).text").String(),
Thumbnails: GetThumbnails(j.Get("thumbnail.musicThumbnailRenderer" +
".thumbnail.thumbnails")),
})
}()
@@ -102,3 +134,37 @@ func ResponsiveListItemRenderer(s gjson.Result) []Item {
return r
}
func NavigationButton(s gjson.Result) []Item {
r := []Item{}
wg := sync.WaitGroup{}
s.ForEach(
func(_, v gjson.Result) bool {
wg.Add(1)
go func() {
defer wg.Done()
j := v.Get("musicNavigationButtonRenderer")
color := j.Get("solid.leftStripeColor").Uint() & 0xffffff
r = append(r, Item{
Id: j.Get("clickCommand.browseEndpoint.params").String(),
Title: RunsText(j.Get("buttonText")),
Sub: fmt.Sprintf("#%06x", color),
})
}()
wg.Wait()
return true
},
)
return r
}
+37 -65
View File
@@ -11,19 +11,9 @@ import (
"github.com/tidwall/gjson"
)
func Fetch(path string, data []byte, c string) (string, int, error) {
func Fetch(path string, data []byte) (string, int, error) {
var query string
if c != "" {
query = "&ctoken=" + c + "&continuation=" + c + "&type=next"
} else {
query = ""
}
url := "https://music.youtube.com/youtubei/v1/" + path + "?key=AIzaSyC9XL3ZjWddXya6X74dJoCTL-WEYFDNX30" + query + "&prettyPrint=false"
log.Println(url)
url := "https://music.youtube.com/youtubei/v1/" + path + "?key=AIzaSyC9XL3ZjWddXya6X74dJoCTL-WEYFDNX30&prettyPrint=false"
req, err := http.NewRequest("POST", url, bytes.NewBuffer(data))
if err != nil {
@@ -54,14 +44,14 @@ func Fetch(path string, data []byte, c string) (string, int, error) {
return string(body), resp.StatusCode, nil
}
func FetchBrowse(id string, c string, browse BrowseData) (string, int) {
func FetchBrowse(id string, browse BrowseData) (string, int) {
data, err := json.Marshal(browse)
if err != nil {
return ErrorMessage(err), 500
}
raw, status, err := Fetch("browse", data, c)
raw, status, err := Fetch("browse", data)
if err != nil {
return ErrorMessage(err), 500
}
@@ -70,39 +60,13 @@ func FetchBrowse(id string, c string, browse BrowseData) (string, int) {
}
func FetchHome(c string) (string, int) {
/* WIP */
id := "FEmusic_home"
if c != "" {
id = ""
}
log.Println(id)
context := GetTypeBrowse("home", id)
raw, status := FetchBrowse(id, c, context)
/*res, err := ParseHome(raw)
if err != nil {
return ErrorMessage(err), 500
}*/
return raw, status
}
func FetchExplore() (string, int) {
id := "FEmusic_explore"
log.Println(id)
context := GetTypeBrowse("", id, "")
context := GetTypeBrowse("", id)
raw, status := FetchBrowse(id, "", context)
raw, status := FetchBrowse(id, context)
res, err := ParseExplore(raw)
if err != nil {
@@ -112,26 +76,43 @@ func FetchExplore() (string, int) {
return res, status
}
func FetchMoods() (string, int) {
/* WIP */
func FetchGenres() (string, int) {
id := "FEmusic_moods_and_genres"
log.Println(id)
context := GetTypeBrowse("", id, "")
context := GetTypeBrowse("", id)
raw, status := FetchBrowse(id, context)
raw, status := FetchBrowse(id, "", context)
res, err := ParseGenres(raw)
if err != nil {
return ErrorMessage(err), 500
}
return raw, status
return res, status
}
func FetchGenre(param string) (string, int) {
id := "FEmusic_moods_and_genres_category"
context := GetTypeBrowse("", id, param)
raw, status := FetchBrowse(id, context)
res, err := ParseGenre(raw)
if err != nil {
return ErrorMessage(err), 500
}
return res, status
}
func FetchArtist(id string) (string, int) {
context := GetTypeBrowse("artist", id)
context := GetTypeBrowse("artist", id, "")
raw, status := FetchBrowse(id, "", context)
raw, status := FetchBrowse(id, context)
res, err := ParseArtist(raw)
if err != nil {
@@ -143,9 +124,9 @@ func FetchArtist(id string) (string, int) {
func FetchLyrics(id string) (string, int) {
context := GetTypeBrowse("lyrics", id)
context := GetTypeBrowse("lyrics", id, "")
raw, status := FetchBrowse(id, "", context)
raw, status := FetchBrowse(id, context)
res, err := ParseLyrics(raw)
if err != nil {
@@ -155,20 +136,11 @@ func FetchLyrics(id string) (string, int) {
return res, status
}
func FetchPlaylist(id string) (string, int) {
context := GetTypeBrowse("playlist", id)
raw, status := FetchBrowse(id, "", context)
return raw, status
}
func FetchAlbum(id string) (string, int) {
context := GetTypeBrowse("album", id)
context := GetTypeBrowse("album", id, "")
raw, status := FetchBrowse(id, "", context)
raw, status := FetchBrowse(id, context)
url := gjson.Parse(raw).Get("microformat.microformatDataRenderer.urlCanonical").String()
@@ -186,7 +158,7 @@ func FetchNext(id string) (string, int) {
return ErrorMessage(err), 500
}
raw, status, err := Fetch("next", data, "")
raw, status, err := Fetch("next", data)
if err != nil {
return ErrorMessage(err), 500
}
+23 -14
View File
@@ -24,14 +24,6 @@ func HandleHealth(c *fiber.Ctx) error {
return c.SendStatus(204)
}
func HandleHome(c *fiber.Ctx) error {
defer calc(c.OriginalURL())()
res, status := FetchHome(c.Params("id"))
return c.Status(status).SendString(res)
}
func HandleExplore(c *fiber.Ctx) error {
defer calc(c.OriginalURL())()
@@ -48,11 +40,31 @@ func HandleNext(c *fiber.Ctx) error {
return c.Status(status).SendString(res)
}
func HandleGenres(c *fiber.Ctx) error {
defer calc(c.OriginalURL())()
res, status := FetchGenres()
return c.Status(status).SendString(res)
}
func HandleGenre(c *fiber.Ctx) error {
defer calc(c.OriginalURL())()
res, status := FetchGenre(c.Params("id"))
return c.Status(status).SendString(res)
}
func HandleBrowse(c *fiber.Ctx) error {
defer calc(c.OriginalURL())()
id := c.Params("id")
if len(id) < 4 {
return c.Status(500).SendString("{\"error\": \"Browse Id is too Short\"}")
}
switch {
case id[:2] == "UC":
res, status := FetchArtist(id)
@@ -63,11 +75,8 @@ func HandleBrowse(c *fiber.Ctx) error {
case id[:4] == "MPRE":
res, status := FetchAlbum(id)
return c.Status(status).SendString(res)
case id[:4] == "VLRD" || id[:2] == "RD":
res, status := FetchPlaylist(id)
return c.Status(status).SendString(res)
default:
return c.SendString("{\"error\": \"Invalid Browse URL\"}")
return c.Status(500).SendString("{\"error\": \"Invalid Browse URL\"}")
}
}
@@ -86,9 +95,9 @@ func main() {
app.Use(recover.New())
app.Get("/healthz", HandleHealth)
app.Get("/home", HandleHome)
app.Get("/home/:id", HandleHome)
app.Get("/explore", HandleExplore)
app.Get("/genres", HandleGenres)
app.Get("/genres/:id", HandleGenre)
app.Get("/next/:id", HandleNext)
app.Get("/browse/:id", HandleBrowse)
app.Get("/channel/:id", HandleArtist)
+72 -105
View File
@@ -2,61 +2,11 @@ package main
import (
"encoding/json"
"log"
"strings"
"sync"
"github.com/tidwall/gjson"
)
func RunsText(j gjson.Result) string {
var s []string
a := j.Get("runs.#.text").Array()
for i := 0; i < len(a); i++ {
s = append(s, a[i].String())
}
return strings.Join(s, "")
}
func GetThumbnails(j gjson.Result) []Thumbnail {
t := []Thumbnail{}
wg := sync.WaitGroup{}
j.ForEach(
func(_, v gjson.Result) bool {
wg.Add(1)
go func() {
defer wg.Done()
u, err := ParseUrl(v.Get("url").String())
if err != nil {
log.Fatal(err)
}
t = append(t, Thumbnail{
Url: u,
Width: v.Get("width").Int(),
Height: v.Get("height").Int(),
})
}()
wg.Wait()
return true
},
)
return t
}
func GetNextSongs(n gjson.Result) []Item {
r := []Item{}
@@ -88,47 +38,24 @@ func GetNextSongs(n gjson.Result) []Item {
return r
}
func ParseHome(raw string) (string, error) {
func ParseExplore(raw string) (string, error) {
j := gjson.Parse(raw)
c := j.Get("contents.singleColumnBrowseResultsRenderer.tabs.0.tabRenderer.content.sectionListRenderer")
c := j.Get("contents.singleColumnBrowseResultsRenderer.tabs.0.tabRenderer.content" +
".tabRenderer.content.sectionListRenderer.contents.#.musicCarouselShelfRenderer")
m := c.Get("contents")
n := c.Get("continuations.0.nextContinuationData.continuation").String()
a := c.Get("#(header.musicCarouselShelfBasicHeaderRenderer" +
".title.runs.0.text == New albums & singles)")
t := c.Get("#(header.musicCarouselShelfBasicHeaderRenderer" +
".title.runs.0.text == Trending)")
var body []map[string]interface{}
m.ForEach(
func(key, value gjson.Result) bool {
var v map[string]interface{}
icsr := value.Get("musicImmersiveCarouselShelfRenderer")
csr := value.Get("musicCarouselShelfRenderer")
switch {
case icsr.Exists():
v = CarouselShelfRenderer(icsr)
case csr.Exists():
v = CarouselShelfRenderer(csr)
default:
v = make(map[string]interface{})
v["raw"] = value.Value()
}
body = append(body, v)
return true
},
)
data := Home{
Contents: body,
Continue: n,
val := Explore{
Albums: TwoRowItemRenderer("album", a.Get("contents")),
Trending: ResponsiveListItemRenderer(t.Get("contents")),
}
res, err := json.Marshal(data)
res, err := json.Marshal(val)
if err != nil {
return "", err
}
@@ -136,18 +63,45 @@ func ParseHome(raw string) (string, error) {
return string(res), nil
}
func ParseExplore(raw string) (string, error) {
func ParseGenres(raw string) (string, error) {
j := gjson.Parse(raw)
c := j.Get("contents.singleColumnBrowseResultsRenderer.tabs.0.tabRenderer.content.sectionListRenderer.contents")
c := j.Get("contents.singleColumnBrowseResultsRenderer.tabs.0.tabRenderer" +
".content.sectionListRenderer.contents.#.gridRenderer")
a := c.Get("#(musicCarouselShelfRenderer.header.musicCarouselShelfBasicHeaderRenderer.title.runs.0.text == New albums & singles).musicCarouselShelfRenderer")
t := c.Get("#(musicCarouselShelfRenderer.header.musicCarouselShelfBasicHeaderRenderer.title.runs.0.text == Trending).musicCarouselShelfRenderer")
m := c.Get("#(header.gridHeaderRenderer.title.runs.0.text == Moods & moments)")
g := c.Get("#(header.gridHeaderRenderer.title.runs.0.text == Genres)")
val := Explore{
Albums: TwoRowItemRenderer("album", a.Get("contents")),
Trending: ResponsiveListItemRenderer(t.Get("contents")),
val := Genres{
Moods: NavigationButton(m.Get("items")),
Genres: NavigationButton(g.Get("items")),
}
res, err := json.Marshal(val)
if err != nil {
return "", err
}
return string(res), nil
}
func ParseGenre(raw string) (string, error) {
j := gjson.Parse(raw)
c := j.Get("contents.singleColumnBrowseResultsRenderer.tabs.0.tabRenderer" +
".content.sectionListRenderer.contents.#.gridRenderer")
s := c.Get("#(header.gridHeaderRenderer.title.runs.0.text == Spotlight)")
f := c.Get("#(header.gridHeaderRenderer.title.runs.0.text == Featured playlists)")
cp := c.Get("#(header.gridHeaderRenderer.title.runs.0.text == Community playlists)")
val := Genre{
Title: RunsText(j.Get("header.musicHeaderRenderer.title")),
Spotlight: TwoRowItemRenderer("", s.Get("items")),
Featured: TwoRowItemRenderer("", f.Get("items")),
Community: TwoRowItemRenderer("", cp.Get("items")),
}
res, err := json.Marshal(val)
@@ -163,20 +117,29 @@ func ParseArtist(raw string) (string, error) {
j := gjson.Parse(raw)
h := j.Get("header.musicImmersiveHeaderRenderer")
c := j.Get("contents.singleColumnBrowseResultsRenderer.tabs.0.tabRenderer.content.sectionListRenderer.contents")
c := j.Get("contents.singleColumnBrowseResultsRenderer.tabs.0.tabRenderer.content" +
".sectionListRenderer.contents")
s := c.Get("#(musicShelfRenderer.title.runs.0.text == Songs).musicShelfRenderer")
a := c.Get("#(musicCarouselShelfRenderer.header.musicCarouselShelfBasicHeaderRenderer.title.runs.0.text == Albums).musicCarouselShelfRenderer")
m := c.Get("#(musicCarouselShelfRenderer.header.musicCarouselShelfBasicHeaderRenderer.title.runs.0.text == Singles).musicCarouselShelfRenderer")
u := c.Get("#(musicCarouselShelfRenderer.header.musicCarouselShelfBasicHeaderRenderer.title.runs.0.text == Fans might also like).musicCarouselShelfRenderer")
a := c.Get("#(musicCarouselShelfRenderer.header.musicCarouselShelfBasicHeaderRenderer" +
".title.runs.0.text == Albums).musicCarouselShelfRenderer")
m := c.Get("#(musicCarouselShelfRenderer.header.musicCarouselShelfBasicHeaderRenderer" +
".title.runs.0.text == Singles).musicCarouselShelfRenderer")
u := c.Get("#(musicCarouselShelfRenderer.header.musicCarouselShelfBasicHeaderRenderer" +
".title.runs.0.text == Fans might also like).musicCarouselShelfRenderer")
val := Artist{
Title: RunsText(h.Get("title")),
Description: RunsText(h.Get("description")),
SubscriberCount: RunsText(h.Get("subscriptionButton.subscribeButtonRenderer.subscriberCountText")),
Thumbnails: GetThumbnails(h.Get("thumbnail.musicThumbnailRenderer.thumbnail.thumbnails")),
BrowsePlaylistId: h.Get("playButton.buttonRenderer.navigationEndpoint.watchEndpoint.playlistId").String(),
PlaylistId: s.Get("contents.0.musicResponsiveListItemRenderer.flexColumns.0.musicResponsiveListItemFlexColumnRenderer.text.runs.0.navigationEndpoint.watchEndpoint.playlistId").String(),
Title: RunsText(h.Get("title")),
Description: RunsText(h.Get("description")),
SubscriberCount: RunsText(h.Get("subscriptionButton" +
".subscribeButtonRenderer.subscriberCountText")),
Thumbnails: GetThumbnails(h.Get("thumbnail.musicThumbnailRenderer" +
".thumbnail.thumbnails")),
BrowsePlaylistId: h.Get("playButton.buttonRenderer.navigationEndpoint" +
".watchEndpoint.playlistId").String(),
PlaylistId: s.Get("contents.0.musicResponsiveListItemRenderer" +
".flexColumns.0.musicResponsiveListItemFlexColumnRenderer.text" +
".runs.0.navigationEndpoint.watchEndpoint.playlistId").String(),
Items: Items{
Songs: ResponsiveListItemRenderer(s.Get("contents")),
Albums: TwoRowItemRenderer("album", a.Get("contents")),
@@ -219,11 +182,15 @@ func ParseNext(raw string) (string, error) {
j := gjson.Parse(raw)
c := j.Get("contents.singleColumnMusicWatchNextResultsRenderer.tabbedRenderer.watchNextTabbedResultsRenderer.tabs")
m := j.Get("playerOverlays.playerOverlayRenderer.browserMediaSession.browserMediaSessionRenderer")
c := j.Get("contents.singleColumnMusicWatchNextResultsRenderer." +
"tabbedRenderer.watchNextTabbedResultsRenderer.tabs")
m := j.Get("playerOverlays.playerOverlayRenderer.browserMediaSession" +
".browserMediaSessionRenderer")
n := c.Get("#(tabRenderer.title == Up next).tabRenderer.content.musicQueueRenderer.content.playlistPanelRenderer")
l := c.Get("#(tabRenderer.title == Lyrics).tabRenderer.endpoint.browseEndpoint.browseId")
n := c.Get("#(tabRenderer.title == Up next).tabRenderer.content" +
".musicQueueRenderer.content.playlistPanelRenderer")
l := c.Get("#(tabRenderer.title == Lyrics).tabRenderer.endpoint" +
".browseEndpoint.browseId")
val := Next{
LyricsId: l.String(),
+36 -28
View File
@@ -10,9 +10,9 @@ type Thumbnail struct {
type Item struct {
Id string `json:"id"`
Title string `json:"title"`
Sub string `json:"subtitle"`
SubId string `json:"subId"`
Thumbnails []Thumbnail `json:"thumbnails"`
Sub string `json:"subtitle,omitempty"`
SubId string `json:"subId,omitempty"`
Thumbnails []Thumbnail `json:"thumbnails,omitempty"`
}
type Items struct {
@@ -22,22 +22,29 @@ type Items struct {
Artists []Item `json:"recommendedArtists"`
}
type Home struct {
Contents []map[string]interface{} `json:"contents"`
Continue string `json:"continue"`
}
type Explore struct {
Albums []Item `json:"albums_and_singles"`
Trending []Item `json:"trending"`
}
type Genres struct {
Moods []Item `json:"moods"`
Genres []Item `json:"genres"`
}
type Genre struct {
Title string `json:"title"`
Spotlight []Item `json:"spotlight"`
Featured []Item `json:"featured"`
Community []Item `json:"community"`
}
type Artist struct {
Title string `json:"title"`
Description string `json:"description"`
BrowsePlaylistId string `json:"browsePlaylistId"`
PlaylistId string `json:"playlistId"`
SubscriberCount string `json:"subscriberCount"`
Description string `json:"description,omitempty"`
BrowsePlaylistId string `json:"browsePlaylistId,omitempty"`
PlaylistId string `json:"playlistId,omitempty"`
SubscriberCount string `json:"subscriberCount,omitempty"`
Thumbnails []Thumbnail `json:"thumbnails"`
Items Items `json:"items"`
}
@@ -60,38 +67,39 @@ type Lyrics struct {
/* Structs and Types */
type Client struct {
Name string `json:"clientName"`
Version string `json:"clientVersion"`
Name string `json:"clientName,omitempty"`
Version string `json:"clientVersion,omitempty"`
}
type Context struct {
Client Client `json:"client"`
Client Client `json:"client",omitempty`
}
type PageType struct {
PageType string `json:"pageType"`
PageType string `json:"pageType",omitempty`
}
type BrowseMusicConfig struct {
MusicConfig PageType `json:"browseEndpointContextMusicConfig"`
MusicConfig PageType `json:"browseEndpointContextMusicConfig,omitempty"`
}
type WatchMusicConfig struct {
Panel bool `json:"hasPersistentPlaylistPanel"`
Type string `json:"musicVideoType"`
Panel bool `json:"hasPersistentPlaylistPanel,omitempty"`
Type string `json:"musicVideoType,omitempty"`
}
type BrowseData struct {
Context Context `json:"context"`
MusicConfig BrowseMusicConfig `json:"browseEndpointContextMusicConfig"`
BrowseId string `json:"browseId"`
Context Context `json:"context,omitempty"`
MusicConfig BrowseMusicConfig `json:"browseEndpointContextMusicConfig,omitempty"`
BrowseId string `json:"browseId,omitempty"`
Params string `json:"params,omitempty"`
}
type NextData struct {
Id string `json:"videoId"`
Context Context `json:"context"`
Audio bool `json:"isAudioOnly"`
Tuner string `json:"tunerSettingValue"`
Panel bool `json:"enablePersistentPlaylistPanel"`
MusicConfig WatchMusicConfig `json:"watchEndpointMusicConfig"`
Id string `json:"videoId,omitempty"`
Context Context `json:"context,omitempty"`
Audio bool `json:"isAudioOnly,omitempty"`
Tuner string `json:"tunerSettingValue,omitempty"`
Panel bool `json:"enablePersistentPlaylistPanel,omitempty"`
MusicConfig WatchMusicConfig `json:"watchEndpointMusicConfig,omitempty"`
}
+2 -1
View File
@@ -9,7 +9,7 @@ var BaseContext = Context{
},
}
func GetTypeBrowse(t, id string) BrowseData {
func GetTypeBrowse(t, id string, params string) BrowseData {
if t != "" {
return BrowseData{
@@ -25,6 +25,7 @@ func GetTypeBrowse(t, id string) BrowseData {
return BrowseData{
Context: BaseContext,
BrowseId: id,
Params: params,
}
}
+18 -1
View File
@@ -2,10 +2,25 @@ package main
import (
"fmt"
"github.com/tidwall/gjson"
"net/url"
"strings"
"time"
)
func RunsText(j gjson.Result) string {
var s []string
a := j.Get("runs.#.text").Array()
for i := 0; i < len(a); i++ {
s = append(s, a[i].String())
}
return strings.Join(s, "")
}
func ParseUrl(raw string) (string, error) {
u, err := url.Parse(raw)
@@ -24,7 +39,9 @@ func ParseUrl(raw string) (string, error) {
}
func ErrorMessage(err error) string {
return fmt.Sprintf("{\"error\": \"%s\", \"message\": \"Please Report this error\"}", err)
data := url.QueryEscape(err.Error())
fmt.Println(err)
return fmt.Sprintf("{\"error\":\"%s\",\"message\":\"Got Error: %s\"}", data)
}
func calc(url string) func() {