mirror of
				https://github.com/iv-org/invidious.git
				synced 2025-11-04 06:31:57 +00:00 
			
		
		
		
	Merge pull request #2787 from matthewmcgarvey/related-channels
Update to fetch related channels again
This commit is contained in:
		@@ -1,33 +1,26 @@
 | 
			
		||||
# TODO: Refactor into either SearchChannel or InvidiousChannel
 | 
			
		||||
struct AboutChannel
 | 
			
		||||
  include DB::Serializable
 | 
			
		||||
record AboutChannel,
 | 
			
		||||
  ucid : String,
 | 
			
		||||
  author : String,
 | 
			
		||||
  auto_generated : Bool,
 | 
			
		||||
  author_url : String,
 | 
			
		||||
  author_thumbnail : String,
 | 
			
		||||
  banner : String?,
 | 
			
		||||
  description_html : String,
 | 
			
		||||
  total_views : Int64,
 | 
			
		||||
  sub_count : Int32,
 | 
			
		||||
  joined : Time,
 | 
			
		||||
  is_family_friendly : Bool,
 | 
			
		||||
  allowed_regions : Array(String),
 | 
			
		||||
  tabs : Array(String)
 | 
			
		||||
 | 
			
		||||
  property ucid : String
 | 
			
		||||
  property author : String
 | 
			
		||||
  property auto_generated : Bool
 | 
			
		||||
  property author_url : String
 | 
			
		||||
  property author_thumbnail : String
 | 
			
		||||
  property banner : String?
 | 
			
		||||
  property description_html : String
 | 
			
		||||
  property total_views : Int64
 | 
			
		||||
  property sub_count : Int32
 | 
			
		||||
  property joined : Time
 | 
			
		||||
  property is_family_friendly : Bool
 | 
			
		||||
  property allowed_regions : Array(String)
 | 
			
		||||
  property related_channels : Array(AboutRelatedChannel)
 | 
			
		||||
  property tabs : Array(String)
 | 
			
		||||
end
 | 
			
		||||
record AboutRelatedChannel,
 | 
			
		||||
  ucid : String,
 | 
			
		||||
  author : String,
 | 
			
		||||
  author_url : String,
 | 
			
		||||
  author_thumbnail : String
 | 
			
		||||
 | 
			
		||||
struct AboutRelatedChannel
 | 
			
		||||
  include DB::Serializable
 | 
			
		||||
 | 
			
		||||
  property ucid : String
 | 
			
		||||
  property author : String
 | 
			
		||||
  property author_url : String
 | 
			
		||||
  property author_thumbnail : String
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
def get_about_info(ucid, locale)
 | 
			
		||||
def get_about_info(ucid, locale) : AboutChannel
 | 
			
		||||
  begin
 | 
			
		||||
    # "EgVhYm91dA==" is the base64-encoded protobuf object {"2:string":"about"}
 | 
			
		||||
    initdata = YoutubeAPI.browse(browse_id: ucid, params: "EgVhYm91dA==")
 | 
			
		||||
@@ -63,8 +56,6 @@ def get_about_info(ucid, locale)
 | 
			
		||||
 | 
			
		||||
    is_family_friendly = initdata["microformat"]["microformatDataRenderer"]["familySafe"].as_bool
 | 
			
		||||
    allowed_regions = initdata["microformat"]["microformatDataRenderer"]["availableCountries"].as_a.map(&.as_s)
 | 
			
		||||
 | 
			
		||||
    related_channels = [] of AboutRelatedChannel
 | 
			
		||||
  else
 | 
			
		||||
    author = initdata["metadata"]["channelMetadataRenderer"]["title"].as_s
 | 
			
		||||
    author_url = initdata["metadata"]["channelMetadataRenderer"]["channelUrl"].as_s
 | 
			
		||||
@@ -85,38 +76,6 @@ def get_about_info(ucid, locale)
 | 
			
		||||
 | 
			
		||||
    is_family_friendly = initdata["microformat"]["microformatDataRenderer"]["familySafe"].as_bool
 | 
			
		||||
    allowed_regions = initdata["microformat"]["microformatDataRenderer"]["availableCountries"].as_a.map(&.as_s)
 | 
			
		||||
 | 
			
		||||
    related_channels = initdata["contents"]["twoColumnBrowseResultsRenderer"]
 | 
			
		||||
      .["secondaryContents"]?.try &.["browseSecondaryContentsRenderer"]["contents"][0]?
 | 
			
		||||
      .try &.["verticalChannelSectionRenderer"]?.try &.["items"]?.try &.as_a.map do |node|
 | 
			
		||||
        renderer = node["miniChannelRenderer"]?
 | 
			
		||||
        related_id = renderer.try &.["channelId"]?.try &.as_s?
 | 
			
		||||
        related_id ||= ""
 | 
			
		||||
 | 
			
		||||
        related_title = renderer.try &.["title"]?.try &.["simpleText"]?.try &.as_s?
 | 
			
		||||
        related_title ||= ""
 | 
			
		||||
 | 
			
		||||
        related_author_url = renderer.try &.["navigationEndpoint"]?.try &.["commandMetadata"]?.try &.["webCommandMetadata"]?
 | 
			
		||||
          .try &.["url"]?.try &.as_s?
 | 
			
		||||
        related_author_url ||= ""
 | 
			
		||||
 | 
			
		||||
        related_author_thumbnails = renderer.try &.["thumbnail"]?.try &.["thumbnails"]?.try &.as_a?
 | 
			
		||||
        related_author_thumbnails ||= [] of JSON::Any
 | 
			
		||||
 | 
			
		||||
        related_author_thumbnail = ""
 | 
			
		||||
        if related_author_thumbnails.size > 0
 | 
			
		||||
          related_author_thumbnail = related_author_thumbnails[-1]["url"]?.try &.as_s?
 | 
			
		||||
          related_author_thumbnail ||= ""
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        AboutRelatedChannel.new({
 | 
			
		||||
          ucid:             related_id,
 | 
			
		||||
          author:           related_title,
 | 
			
		||||
          author_url:       related_author_url,
 | 
			
		||||
          author_thumbnail: related_author_thumbnail,
 | 
			
		||||
        })
 | 
			
		||||
      end
 | 
			
		||||
    related_channels ||= [] of AboutRelatedChannel
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  total_views = 0_i64
 | 
			
		||||
@@ -155,20 +114,44 @@ def get_about_info(ucid, locale)
 | 
			
		||||
  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,
 | 
			
		||||
    total_views:        total_views,
 | 
			
		||||
    sub_count:          sub_count,
 | 
			
		||||
    joined:             joined,
 | 
			
		||||
  AboutChannel.new(
 | 
			
		||||
    ucid: ucid,
 | 
			
		||||
    author: author,
 | 
			
		||||
    auto_generated: auto_generated,
 | 
			
		||||
    author_url: author_url,
 | 
			
		||||
    author_thumbnail: author_thumbnail,
 | 
			
		||||
    banner: banner,
 | 
			
		||||
    description_html: description_html,
 | 
			
		||||
    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,
 | 
			
		||||
  })
 | 
			
		||||
    allowed_regions: allowed_regions,
 | 
			
		||||
    tabs: tabs,
 | 
			
		||||
  )
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
def fetch_related_channels(about_channel : AboutChannel) : Array(AboutRelatedChannel)
 | 
			
		||||
  # params is {"2:string":"channels"} encoded
 | 
			
		||||
  channels = YoutubeAPI.browse(browse_id: about_channel.ucid, params: "EghjaGFubmVscw%3D%3D")
 | 
			
		||||
 | 
			
		||||
  tabs = channels.dig?("contents", "twoColumnBrowseResultsRenderer", "tabs").try(&.as_a?) || [] of JSON::Any
 | 
			
		||||
  tab = tabs.find { |tab| tab.dig?("tabRenderer", "title").try(&.as_s?) == "Channels" }
 | 
			
		||||
  return [] of AboutRelatedChannel if tab.nil?
 | 
			
		||||
 | 
			
		||||
  items = tab.dig?("tabRenderer", "content", "sectionListRenderer", "contents", 0, "itemSectionRenderer", "contents", 0, "gridRenderer", "items").try(&.as_a?) || [] of JSON::Any
 | 
			
		||||
 | 
			
		||||
  items.map do |item|
 | 
			
		||||
    related_id = item.dig("gridChannelRenderer", "channelId").as_s
 | 
			
		||||
    related_title = item.dig("gridChannelRenderer", "title", "simpleText").as_s
 | 
			
		||||
    related_author_url = item.dig("gridChannelRenderer", "navigationEndpoint", "browseEndpoint", "canonicalBaseUrl").as_s
 | 
			
		||||
    related_author_thumbnail = item.dig("gridChannelRenderer", "thumbnail", "thumbnails", -1, "url").as_s
 | 
			
		||||
 | 
			
		||||
    AboutRelatedChannel.new(
 | 
			
		||||
      ucid: related_id,
 | 
			
		||||
      author: related_title,
 | 
			
		||||
      author_url: related_author_url,
 | 
			
		||||
      author_thumbnail: related_author_thumbnail,
 | 
			
		||||
    )
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 
 | 
			
		||||
@@ -96,7 +96,7 @@ module Invidious::Routes::API::V1::Channels
 | 
			
		||||
 | 
			
		||||
        json.field "relatedChannels" do
 | 
			
		||||
          json.array do
 | 
			
		||||
            channel.related_channels.each do |related_channel|
 | 
			
		||||
            fetch_related_channels(channel).each do |related_channel|
 | 
			
		||||
              json.object do
 | 
			
		||||
                json.field "author", related_channel.author
 | 
			
		||||
                json.field "authorId", related_channel.ucid
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user