mirror of
https://github.com/iv-org/invidious.git
synced 2026-08-17 05:20:51 -05:00
feat: Use Innertube instead of channel RSS feeds to update channels
This commit is contained in:
parent
3383a3041f
commit
be306c01b2
@ -159,32 +159,16 @@ def fetch_channel(ucid, pull_all_videos : Bool)
|
|||||||
LOGGER.debug("fetch_channel: #{ucid}")
|
LOGGER.debug("fetch_channel: #{ucid}")
|
||||||
LOGGER.trace("fetch_channel: #{ucid} : pull_all_videos = #{pull_all_videos}")
|
LOGGER.trace("fetch_channel: #{ucid} : pull_all_videos = #{pull_all_videos}")
|
||||||
|
|
||||||
namespaces = {
|
# Deleted channels raise a `InfoException` exception.
|
||||||
"yt" => "http://www.youtube.com/xml/schemas/2015",
|
begin
|
||||||
"media" => "http://search.yahoo.com/mrss/",
|
channel = get_about_info(ucid, nil)
|
||||||
"default" => "http://www.w3.org/2005/Atom",
|
rescue ex
|
||||||
}
|
raise ex
|
||||||
|
|
||||||
LOGGER.trace("fetch_channel: #{ucid} : Downloading RSS feed")
|
|
||||||
rss = YT_POOL.client &.get("/feeds/videos.xml?channel_id=#{ucid}").body
|
|
||||||
LOGGER.trace("fetch_channel: #{ucid} : Parsing RSS feed")
|
|
||||||
rss = XML.parse(rss)
|
|
||||||
|
|
||||||
author = rss.xpath_node("//default:feed/default:title", namespaces)
|
|
||||||
if !author
|
|
||||||
raise InfoException.new("Deleted or invalid channel")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
author = author.content
|
author = channel.author
|
||||||
|
|
||||||
# Auto-generated channels
|
LOGGER.trace("fetch_channel: #{ucid} : author = #{author}, auto_generated = #{channel.auto_generated}")
|
||||||
# https://support.google.com/youtube/answer/2579942
|
|
||||||
if author.ends_with?(" - Topic") ||
|
|
||||||
{"Popular on YouTube", "Music", "Sports", "Gaming"}.includes? author
|
|
||||||
auto_generated = true
|
|
||||||
end
|
|
||||||
|
|
||||||
LOGGER.trace("fetch_channel: #{ucid} : author = #{author}, auto_generated = #{auto_generated}")
|
|
||||||
|
|
||||||
channel = InvidiousChannel.new({
|
channel = InvidiousChannel.new({
|
||||||
id: ucid,
|
id: ucid,
|
||||||
@ -197,61 +181,32 @@ def fetch_channel(ucid, pull_all_videos : Bool)
|
|||||||
LOGGER.trace("fetch_channel: #{ucid} : Downloading channel videos page")
|
LOGGER.trace("fetch_channel: #{ucid} : Downloading channel videos page")
|
||||||
videos, continuation = IV::Channel::Tabs.get_videos(channel)
|
videos, continuation = IV::Channel::Tabs.get_videos(channel)
|
||||||
|
|
||||||
LOGGER.trace("fetch_channel: #{ucid} : Extracting videos from channel RSS feed")
|
LOGGER.trace("fetch_channel: #{ucid} : Extracting videos from channel")
|
||||||
rss.xpath_nodes("//default:feed/default:entry", namespaces).each do |entry|
|
videos.select(SearchVideo).each do |video|
|
||||||
video_id = entry.xpath_node("yt:videoId", namespaces).not_nil!.content
|
new_video = ChannelVideo.new({
|
||||||
title = entry.xpath_node("default:title", namespaces).not_nil!.content
|
id: video.id,
|
||||||
|
title: video.title,
|
||||||
published = Time.parse_rfc3339(
|
published: video.published,
|
||||||
entry.xpath_node("default:published", namespaces).not_nil!.content
|
updated: Time.utc,
|
||||||
)
|
ucid: video.ucid,
|
||||||
updated = Time.parse_rfc3339(
|
author: video.author,
|
||||||
entry.xpath_node("default:updated", namespaces).not_nil!.content
|
length_seconds: video.length_seconds,
|
||||||
)
|
live_now: video.badges.live_now?,
|
||||||
|
premiere_timestamp: video.premiere_timestamp,
|
||||||
author = entry.xpath_node("default:author/default:name", namespaces).not_nil!.content
|
views: video.views,
|
||||||
ucid = entry.xpath_node("yt:channelId", namespaces).not_nil!.content
|
|
||||||
|
|
||||||
views = entry
|
|
||||||
.xpath_node("media:group/media:community/media:statistics", namespaces)
|
|
||||||
.try &.["views"]?.try &.to_i64? || 0_i64
|
|
||||||
|
|
||||||
channel_video = videos
|
|
||||||
.select(SearchVideo)
|
|
||||||
.select(&.id.== video_id)[0]?
|
|
||||||
|
|
||||||
length_seconds = channel_video.try &.length_seconds
|
|
||||||
length_seconds ||= 0
|
|
||||||
|
|
||||||
live_now = channel_video.try &.badges.live_now?
|
|
||||||
live_now ||= false
|
|
||||||
|
|
||||||
premiere_timestamp = channel_video.try &.premiere_timestamp
|
|
||||||
|
|
||||||
video = ChannelVideo.new({
|
|
||||||
id: video_id,
|
|
||||||
title: title,
|
|
||||||
published: published,
|
|
||||||
updated: updated,
|
|
||||||
ucid: ucid,
|
|
||||||
author: author,
|
|
||||||
length_seconds: length_seconds,
|
|
||||||
live_now: live_now,
|
|
||||||
premiere_timestamp: premiere_timestamp,
|
|
||||||
views: views,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
LOGGER.trace("fetch_channel: #{ucid} : video #{video_id} : Updating or inserting video")
|
LOGGER.trace("fetch_channel: #{ucid} : video #{new_video.id} : Updating or inserting video")
|
||||||
|
|
||||||
# We don't include the 'premiere_timestamp' here because channel pages don't include them,
|
# We don't include the 'premiere_timestamp' here because channel pages don't include them,
|
||||||
# meaning the above timestamp is always null
|
# meaning the above timestamp is always null
|
||||||
was_insert = Invidious::Database::ChannelVideos.insert(video)
|
was_insert = Invidious::Database::ChannelVideos.insert(new_video)
|
||||||
|
|
||||||
if was_insert
|
if was_insert
|
||||||
LOGGER.trace("fetch_channel: #{ucid} : video #{video_id} : Inserted, updating subscriptions")
|
LOGGER.trace("fetch_channel: #{ucid} : video #{new_video.id} : Inserted, updating subscriptions")
|
||||||
NOTIFICATION_CHANNEL.send(VideoNotification.from_video(video))
|
NOTIFICATION_CHANNEL.send(VideoNotification.from_video(new_video))
|
||||||
else
|
else
|
||||||
LOGGER.trace("fetch_channel: #{ucid} : video #{video_id} : Updated")
|
LOGGER.trace("fetch_channel: #{ucid} : video #{new_video.id} : Updated")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -43,7 +43,7 @@ class Invidious::Jobs::RefreshChannelsJob < Invidious::Jobs::BaseJob
|
|||||||
end
|
end
|
||||||
rescue ex
|
rescue ex
|
||||||
LOGGER.error("RefreshChannelsJob: #{id} : #{ex.message}")
|
LOGGER.error("RefreshChannelsJob: #{id} : #{ex.message}")
|
||||||
if ex.message == "Deleted or invalid channel"
|
if ex.is_a?(InfoException)
|
||||||
Invidious::Database::Channels.update_mark_deleted(id)
|
Invidious::Database::Channels.update_mark_deleted(id)
|
||||||
else
|
else
|
||||||
lim_fibers = 1
|
lim_fibers = 1
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user