mirror of
https://github.com/iv-org/invidious.git
synced 2025-01-09 19:10:34 +05:30
extract islisted info + throw error only on not found video
This commit is contained in:
parent
2a40f3b9c5
commit
9438a6df35
@ -326,15 +326,16 @@ end
|
|||||||
def fetch_video(id, region)
|
def fetch_video(id, region)
|
||||||
info = extract_video_info(video_id: id)
|
info = extract_video_info(video_id: id)
|
||||||
|
|
||||||
if info["reason"]?
|
if info["reason"]? && info["subreason"]?
|
||||||
reason = info["reason"].as_s
|
reason = info["reason"].as_s
|
||||||
if info.dig?("subreason")
|
puts info
|
||||||
|
if info.dig?("subreason").nil?
|
||||||
subreason = info["subreason"].as_s
|
subreason = info["subreason"].as_s
|
||||||
else
|
else
|
||||||
subreason = "No additional reason"
|
subreason = "No additional reason"
|
||||||
end
|
end
|
||||||
if reason == "Video unavailable"
|
if reason == "Video unavailable"
|
||||||
raise NotFoundException.new(reason + ": " + subreason || "")
|
raise NotFoundException.new(reason + ": Video not found" || "")
|
||||||
elsif {"Private video"}.any?(reason)
|
elsif {"Private video"}.any?(reason)
|
||||||
raise InfoException.new(reason + ": " + subreason || "")
|
raise InfoException.new(reason + ": " + subreason || "")
|
||||||
end
|
end
|
||||||
|
@ -70,9 +70,10 @@ def extract_video_info(video_id : String)
|
|||||||
subreason = subreason_main.try &.[]?("simpleText").try &.as_s
|
subreason = subreason_main.try &.[]?("simpleText").try &.as_s
|
||||||
subreason ||= subreason_main.try &.[]("runs").as_a.map(&.[]("text")).join("")
|
subreason ||= subreason_main.try &.[]("runs").as_a.map(&.[]("text")).join("")
|
||||||
|
|
||||||
# Stop here if video is not a scheduled livestream or
|
# Stop if private video or video not found.
|
||||||
# for LOGIN_REQUIRED when videoDetails element is not found because retrying won't help
|
# But for video unavailable, only stop if playability_status is ERROR because playability_status UNPLAYABLE
|
||||||
if {"Private video", "Video unavailable"}.any?(reason)
|
# still gives all the necessary info for displaying the video page (title, description and more)
|
||||||
|
if {"Private video", "Video unavailable"}.any?(reason) && !{"UNPLAYABLE"}.any?(playability_status)
|
||||||
return {
|
return {
|
||||||
"version" => JSON::Any.new(Video::SCHEMA_VERSION.to_i64),
|
"version" => JSON::Any.new(Video::SCHEMA_VERSION.to_i64),
|
||||||
"reason" => JSON::Any.new(reason),
|
"reason" => JSON::Any.new(reason),
|
||||||
@ -232,6 +233,10 @@ def parse_video_info(video_id : String, player_response : Hash(String, JSON::Any
|
|||||||
length_txt = (microformat["lengthSeconds"]? || video_details["lengthSeconds"]?)
|
length_txt = (microformat["lengthSeconds"]? || video_details["lengthSeconds"]?)
|
||||||
.try &.as_s.to_i64
|
.try &.as_s.to_i64
|
||||||
|
|
||||||
|
published = microformat["publishDate"]?
|
||||||
|
.try { |t| Time.parse(t.as_s, "%Y-%m-%d", Time::Location::UTC) }
|
||||||
|
|
||||||
|
if !published
|
||||||
published_txt = video_primary_renderer
|
published_txt = video_primary_renderer
|
||||||
.try &.dig?("dateText", "simpleText")
|
.try &.dig?("dateText", "simpleText")
|
||||||
|
|
||||||
@ -242,6 +247,7 @@ def parse_video_info(video_id : String, player_response : Hash(String, JSON::Any
|
|||||||
else
|
else
|
||||||
published = Time.utc
|
published = Time.utc
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
premiere_timestamp = microformat.dig?("liveBroadcastDetails", "startTimestamp")
|
premiere_timestamp = microformat.dig?("liveBroadcastDetails", "startTimestamp")
|
||||||
.try { |t| Time.parse_rfc3339(t.as_s) }
|
.try { |t| Time.parse_rfc3339(t.as_s) }
|
||||||
@ -260,8 +266,24 @@ def parse_video_info(video_id : String, player_response : Hash(String, JSON::Any
|
|||||||
.try &.as_a.map &.as_s || [] of String
|
.try &.as_a.map &.as_s || [] of String
|
||||||
|
|
||||||
allow_ratings = video_details["allowRatings"]?.try &.as_bool
|
allow_ratings = video_details["allowRatings"]?.try &.as_bool
|
||||||
|
|
||||||
family_friendly = microformat["isFamilySafe"]?.try &.as_bool
|
family_friendly = microformat["isFamilySafe"]?.try &.as_bool
|
||||||
|
if family_friendly.nil?
|
||||||
|
family_friendly = true # if isFamilySafe not found then assume is safe
|
||||||
|
end
|
||||||
|
|
||||||
is_listed = video_details["isCrawlable"]?.try &.as_bool
|
is_listed = video_details["isCrawlable"]?.try &.as_bool
|
||||||
|
if video_badges = video_primary_renderer.try &.dig?("badges")
|
||||||
|
if has_unlisted_badge?(video_badges)
|
||||||
|
is_listed ||= false
|
||||||
|
else
|
||||||
|
is_listed ||= true
|
||||||
|
end
|
||||||
|
# if no badges but videoDetails not available then assume isListed
|
||||||
|
else
|
||||||
|
is_listed ||= true
|
||||||
|
end
|
||||||
|
|
||||||
is_upcoming = video_details["isUpcoming"]?.try &.as_bool
|
is_upcoming = video_details["isUpcoming"]?.try &.as_bool
|
||||||
|
|
||||||
keywords = video_details["keywords"]?
|
keywords = video_details["keywords"]?
|
||||||
@ -417,6 +439,9 @@ def parse_video_info(video_id : String, player_response : Hash(String, JSON::Any
|
|||||||
|
|
||||||
# Author infos
|
# Author infos
|
||||||
|
|
||||||
|
author = video_details["author"]?.try &.as_s
|
||||||
|
ucid = video_details["channelId"]?.try &.as_s
|
||||||
|
|
||||||
if author_info = video_secondary_renderer.try &.dig?("owner", "videoOwnerRenderer")
|
if author_info = video_secondary_renderer.try &.dig?("owner", "videoOwnerRenderer")
|
||||||
author_thumbnail = author_info.dig?("thumbnail", "thumbnails", 0, "url")
|
author_thumbnail = author_info.dig?("thumbnail", "thumbnails", 0, "url")
|
||||||
author_verified = has_verified_badge?(author_info["badges"]?)
|
author_verified = has_verified_badge?(author_info["badges"]?)
|
||||||
@ -425,8 +450,8 @@ def parse_video_info(video_id : String, player_response : Hash(String, JSON::Any
|
|||||||
.try { |t| t["simpleText"]? || t.dig?("runs", 0, "text") }
|
.try { |t| t["simpleText"]? || t.dig?("runs", 0, "text") }
|
||||||
.try &.as_s.split(" ", 2)[0]
|
.try &.as_s.split(" ", 2)[0]
|
||||||
|
|
||||||
author = author_info.dig?("title", "runs", 0, "text").try &.as_s
|
author ||= author_info.dig?("title", "runs", 0, "text").try &.as_s
|
||||||
ucid = author_info.dig?("title", "runs", 0, "navigationEndpoint", "browseEndpoint", "browseId").try &.as_s
|
ucid ||= author_info.dig?("title", "runs", 0, "navigationEndpoint", "browseEndpoint", "browseId").try &.as_s
|
||||||
end
|
end
|
||||||
|
|
||||||
# Return data
|
# Return data
|
||||||
@ -451,8 +476,8 @@ def parse_video_info(video_id : String, player_response : Hash(String, JSON::Any
|
|||||||
# Extra video infos
|
# Extra video infos
|
||||||
"allowedRegions" => JSON::Any.new(allowed_regions.map { |v| JSON::Any.new(v) }),
|
"allowedRegions" => JSON::Any.new(allowed_regions.map { |v| JSON::Any.new(v) }),
|
||||||
"allowRatings" => JSON::Any.new(allow_ratings || false),
|
"allowRatings" => JSON::Any.new(allow_ratings || false),
|
||||||
"isFamilyFriendly" => JSON::Any.new(family_friendly || true),
|
"isFamilyFriendly" => JSON::Any.new(family_friendly),
|
||||||
"isListed" => JSON::Any.new(is_listed || false),
|
"isListed" => JSON::Any.new(is_listed),
|
||||||
"isUpcoming" => JSON::Any.new(is_upcoming || false),
|
"isUpcoming" => JSON::Any.new(is_upcoming || false),
|
||||||
"keywords" => JSON::Any.new(keywords.map { |v| JSON::Any.new(v) }),
|
"keywords" => JSON::Any.new(keywords.map { |v| JSON::Any.new(v) }),
|
||||||
"isPostLiveDvr" => JSON::Any.new(post_live_dvr),
|
"isPostLiveDvr" => JSON::Any.new(post_live_dvr),
|
||||||
|
@ -68,6 +68,23 @@ rescue ex
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def has_unlisted_badge?(badges : JSON::Any?)
|
||||||
|
return false if badges.nil?
|
||||||
|
|
||||||
|
badges.as_a.each do |badge|
|
||||||
|
icon_type = badge.dig("metadataBadgeRenderer", "icon", "iconType").as_s
|
||||||
|
|
||||||
|
return true if icon_type == "PRIVACY_UNLISTED"
|
||||||
|
end
|
||||||
|
|
||||||
|
return false
|
||||||
|
rescue ex
|
||||||
|
LOGGER.debug("Unable to parse owner badges. Got exception: #{ex.message}")
|
||||||
|
LOGGER.trace("Owner badges data: #{badges.to_json}")
|
||||||
|
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
# This function extracts SearchVideo items from a Category.
|
# This function extracts SearchVideo items from a Category.
|
||||||
# Categories are commonly returned in search results and trending pages.
|
# Categories are commonly returned in search results and trending pages.
|
||||||
def extract_category(category : Category) : Array(SearchVideo)
|
def extract_category(category : Category) : Array(SearchVideo)
|
||||||
|
Loading…
Reference in New Issue
Block a user