diff options
| author | syeopite <syeopite@syeopite.dev> | 2021-04-02 20:58:39 -0700 |
|---|---|---|
| committer | syeopite <syeopite@syeopite.dev> | 2021-04-03 20:26:38 -0700 |
| commit | fe4eef585523ea1e805afdfa106b7dde1f458f7e (patch) | |
| tree | d1cdf52b245759aeb776d45b59daca92eb3c421c /src | |
| parent | c0997f951c9af58a844d6098398ce0a39e43d052 (diff) | |
| download | invidious-fe4eef585523ea1e805afdfa106b7dde1f458f7e.tar.gz invidious-fe4eef585523ea1e805afdfa106b7dde1f458f7e.tar.bz2 invidious-fe4eef585523ea1e805afdfa106b7dde1f458f7e.zip | |
Fix channel info extract for 'video game' channels
Diffstat (limited to 'src')
| -rw-r--r-- | src/invidious/channels.cr | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/src/invidious/channels.cr b/src/invidious/channels.cr index 47dfcbd6..014df8d5 100644 --- a/src/invidious/channels.cr +++ b/src/invidious/channels.cr @@ -821,6 +821,19 @@ def get_about_info(ucid, locale) raise ChannelRedirect.new(channel_id: browse_endpoint["browseId"].to_s) end + auto_generated = false + if !initdata.has_key?("metadata") + auto_generated = true + end + + if auto_generated + return get_auto_generated_channel_info(initdata, about, ucid) + else + return get_normal_channel_info(initdata, about) + end +end + +def get_normal_channel_info(initdata, about) author = initdata["metadata"]["channelMetadataRenderer"]["title"].as_s author_url = initdata["metadata"]["channelMetadataRenderer"]["channelUrl"].as_s author_thumbnail = initdata["metadata"]["channelMetadataRenderer"]["avatar"]["thumbnails"][0]["url"].as_s @@ -929,6 +942,69 @@ def get_about_info(ucid, locale) }) end +def get_auto_generated_channel_info(initdata, about, ucid) + author = initdata["header"]["interactiveTabbedHeaderRenderer"]["title"]["simpleText"].as_s + author_url = initdata["microformat"]["microformatDataRenderer"]["urlCanonical"].as_s + author_thumbnail = initdata["header"]["interactiveTabbedHeaderRenderer"]["boxArt"]["thumbnails"][0]["url"].as_s + + # Raises a KeyError on failure. + banners = initdata["header"]["interactiveTabbedHeaderRenderer"]?.try &.["banner"]?.try &.["thumbnails"]? + banner = banners.try &.[-1]?.try &.["url"].as_s? + + description = initdata["header"]["interactiveTabbedHeaderRenderer"]["description"]["simpleText"].as_s + description_html = HTML.escape(description).gsub("\n", "<br>") + + paid = false + is_family_friendly = initdata["microformat"]["microformatDataRenderer"]["familySafe"].as_bool + allowed_regions = initdata["microformat"]["microformatDataRenderer"]["availableCountries"].as_a.map { |a| a.as_s } + + related_channels = [] of AboutRelatedChannel + + total_views = 0_i64 + joined = Time.unix(0) + tabs = [] of String + auto_generated = true + + tabs_json = initdata["contents"]["twoColumnBrowseResultsRenderer"]["tabs"]?.try &.as_a? + if !tabs_json.nil? + # Retrieve information from the tabs array. The index we are looking for varies between channels. + tabs_json.each do |node| + # Try to find the about section which is located in only one of the tabs. + channel_about_meta = node["tabRenderer"]?.try &.["content"]?.try &.["sectionListRenderer"]? + .try &.["contents"]?.try &.[0]?.try &.["itemSectionRenderer"]?.try &.["contents"]? + .try &.[0]?.try &.["channelAboutFullMetadataRenderer"]? + + if !channel_about_meta.nil? + # The joined text is split to several sub strings. The reduce joins those strings before parsing the date. + joined = channel_about_meta["joinedDateText"]?.try &.["runs"]?.try &.as_a.reduce("") { |acc, node| acc + node["text"].as_s } + .try { |text| Time.parse(text, "Joined %b %-d, %Y", Time::Location.local) } || Time.unix(0) + end + end + tabs = tabs_json.reject { |node| node["tabRenderer"]?.nil? }.map { |node| node["tabRenderer"]["title"].as_s.downcase } + end + + sub_count = initdata["header"]["c4TabbedHeaderRenderer"]?.try &.["subscriberCountText"]?.try &.["simpleText"]?.try &.as_s? + .try { |text| short_text_to_number(text.split(" ")[0]) } || 0 + + AboutChannel.new({ + ucid: ucid, + author: author, + auto_generated: auto_generated, + author_url: author_url, + author_thumbnail: author_thumbnail, + banner: banner, + description_html: description_html, + paid: paid, + total_views: total_views, + sub_count: sub_count, + joined: joined, + is_family_friendly: is_family_friendly, + allowed_regions: allowed_regions, + related_channels: related_channels, + tabs: tabs, + }) +end + def get_channel_videos_response(ucid, page = 1, auto_generated = nil, sort_by = "newest") continuation = produce_channel_videos_continuation(ucid, page, auto_generated: auto_generated, sort_by: sort_by, v2: true) |
