Merge pull request #3700 from ChunkyProgrammer/fix-shorts

Fix parsing shorts on channel page
This commit is contained in:
Émilien Devos (perso) 2023-04-05 17:22:09 +02:00 committed by GitHub
commit 525e4bd67a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 36 additions and 60 deletions

View File

@ -129,38 +129,15 @@ module Invidious::Channel::Tabs
# Shorts # Shorts
# ------------------- # -------------------
private def fetch_shorts_data(ucid : String, continuation : String? = nil) def get_shorts(channel : AboutChannel, continuation : String? = nil)
if continuation.nil? if continuation.nil?
# EgZzaG9ydHPyBgUKA5oBAA%3D%3D is the protobuf object to load "shorts" # EgZzaG9ydHPyBgUKA5oBAA%3D%3D is the protobuf object to load "shorts"
# TODO: try to extract the continuation tokens that allows other sorting options # TODO: try to extract the continuation tokens that allows other sorting options
return YoutubeAPI.browse(ucid, params: "EgZzaG9ydHPyBgUKA5oBAA%3D%3D") initial_data = YoutubeAPI.browse(channel.ucid, params: "EgZzaG9ydHPyBgUKA5oBAA%3D%3D")
else else
return YoutubeAPI.browse(continuation: continuation) initial_data = YoutubeAPI.browse(continuation: continuation)
end end
end
def get_shorts(channel : AboutChannel, continuation : String? = nil)
initial_data = self.fetch_shorts_data(channel.ucid, continuation)
begin
# Try to parse the initial data fetched above
return extract_items(initial_data, channel.author, channel.ucid) return extract_items(initial_data, channel.author, channel.ucid)
rescue ex : RetryOnceException
# Sometimes, for a completely unknown reason, the "reelItemRenderer"
# object is missing some critical information (it happens once in about
# 20 subsequent requests). Refreshing the page is required to properly
# show the "shorts" tab.
#
# In order to make the experience smoother for the user, we simulate
# said page refresh by fetching again the JSON. If that still doesn't
# work, we raise a BrokenTubeException, as something is really broken.
begin
initial_data = self.fetch_shorts_data(channel.ucid, continuation)
return extract_items(initial_data, channel.author, channel.ucid)
rescue ex : RetryOnceException
raise BrokenTubeException.new "reelPlayerHeaderSupportedRenderers"
end
end
end end
# ------------------- # -------------------

View File

@ -448,18 +448,10 @@ private module Parsers
"overlay", "reelPlayerOverlayRenderer" "overlay", "reelPlayerOverlayRenderer"
) )
# Sometimes, the "reelPlayerOverlayRenderer" object is missing the if video_details_container = reel_player_overlay.dig?(
# important part of the response. We use this exception to tell
# the calling function to fetch the content again.
if !reel_player_overlay.as_h.has_key?("reelPlayerHeaderSupportedRenderers")
raise RetryOnceException.new
end
video_details_container = reel_player_overlay.dig(
"reelPlayerHeaderSupportedRenderers", "reelPlayerHeaderSupportedRenderers",
"reelPlayerHeaderRenderer" "reelPlayerHeaderRenderer"
) )
# Author infos # Author infos
author = video_details_container author = video_details_container
@ -480,12 +472,19 @@ private module Parsers
.try { |t| decode_date(t.as_s) } || Time.utc .try { |t| decode_date(t.as_s) } || Time.utc
# View count # View count
view_count_text = video_details_container.dig?("viewCountText", "simpleText")
else
author = author_fallback.name
ucid = author_fallback.id
published = Time.utc
title = item_contents.dig?("headline", "simpleText").try &.as_s || ""
end
# View count
# View count used to be in the reelWatchEndpoint, but that changed? # View count used to be in the reelWatchEndpoint, but that changed?
view_count_text = item_contents.dig?("viewCountText", "simpleText") view_count_text ||= item_contents.dig?("viewCountText", "simpleText")
view_count_text ||= video_details_container.dig?("viewCountText", "simpleText")
view_count = view_count_text.try &.as_s.gsub(/\D+/, "").to_i64? || 0_i64 view_count = short_text_to_number(view_count_text.try &.as_s || "0")
# Duration # Duration