|
|
@ -144,8 +144,6 @@ module Invidious::Routes::Feeds
|
|
|
|
|
|
|
|
|
|
|
|
ucid = env.params.url["ucid"]
|
|
|
|
ucid = env.params.url["ucid"]
|
|
|
|
|
|
|
|
|
|
|
|
params = HTTP::Params.parse(env.params.query["params"]? || "")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
begin
|
|
|
|
begin
|
|
|
|
channel = get_about_info(ucid, locale)
|
|
|
|
channel = get_about_info(ucid, locale)
|
|
|
|
rescue ex : ChannelRedirect
|
|
|
|
rescue ex : ChannelRedirect
|
|
|
@ -159,12 +157,13 @@ module Invidious::Routes::Feeds
|
|
|
|
response = YT_POOL.client &.get("/feeds/videos.xml?channel_id=#{channel.ucid}")
|
|
|
|
response = YT_POOL.client &.get("/feeds/videos.xml?channel_id=#{channel.ucid}")
|
|
|
|
rss = XML.parse_html(response.body)
|
|
|
|
rss = XML.parse_html(response.body)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
updated = [] of String
|
|
|
|
videos = rss.xpath_nodes("//feed/entry").map do |entry|
|
|
|
|
videos = rss.xpath_nodes("//feed/entry").map do |entry|
|
|
|
|
video_id = entry.xpath_node("videoid").not_nil!.content
|
|
|
|
video_id = entry.xpath_node("videoid").not_nil!.content
|
|
|
|
title = entry.xpath_node("title").not_nil!.content
|
|
|
|
title = entry.xpath_node("title").not_nil!.content
|
|
|
|
|
|
|
|
|
|
|
|
published = Time.parse_rfc3339(entry.xpath_node("published").not_nil!.content)
|
|
|
|
published = Time.parse_rfc3339(entry.xpath_node("published").not_nil!.content)
|
|
|
|
updated = Time.parse_rfc3339(entry.xpath_node("updated").not_nil!.content)
|
|
|
|
updated << entry.xpath_node("updated").not_nil!.content
|
|
|
|
|
|
|
|
|
|
|
|
author = entry.xpath_node("author/name").not_nil!.content
|
|
|
|
author = entry.xpath_node("author/name").not_nil!.content
|
|
|
|
ucid = entry.xpath_node("channelid").not_nil!.content
|
|
|
|
ucid = entry.xpath_node("channelid").not_nil!.content
|
|
|
@ -188,33 +187,27 @@ module Invidious::Routes::Feeds
|
|
|
|
})
|
|
|
|
})
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
XML.build(indent: " ", encoding: "UTF-8") do |xml|
|
|
|
|
feed_created = rss.xpath_node("//feed/published").not_nil!.content
|
|
|
|
xml.element("feed", "xmlns:yt": "http://www.youtube.com/xml/schemas/2015",
|
|
|
|
feed_updated = updated.size > 0 ? updated[0] : feed_created
|
|
|
|
"xmlns:media": "http://search.yahoo.com/mrss/", xmlns: "http://www.w3.org/2005/Atom",
|
|
|
|
|
|
|
|
"xml:lang": "en-US") do
|
|
|
|
|
|
|
|
xml.element("link", rel: "self", href: "#{HOST_URL}#{env.request.resource}")
|
|
|
|
|
|
|
|
xml.element("id") { xml.text "yt:channel:#{channel.ucid}" }
|
|
|
|
|
|
|
|
xml.element("yt:channelId") { xml.text channel.ucid }
|
|
|
|
|
|
|
|
xml.element("icon") { xml.text channel.author_thumbnail }
|
|
|
|
|
|
|
|
xml.element("title") { xml.text channel.author }
|
|
|
|
|
|
|
|
xml.element("link", rel: "alternate", href: "#{HOST_URL}/channel/#{channel.ucid}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
xml.element("author") do
|
|
|
|
# Generate Atom feed
|
|
|
|
xml.element("name") { xml.text channel.author }
|
|
|
|
|
|
|
|
xml.element("uri") { xml.text "#{HOST_URL}/channel/#{channel.ucid}" }
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
xml.element("image") do
|
|
|
|
properties = Invidious::RssAtom::AtomProperties.new(
|
|
|
|
xml.element("url") { xml.text channel.author_thumbnail }
|
|
|
|
title: "", # Use channel author name
|
|
|
|
xml.element("title") { xml.text channel.author }
|
|
|
|
icon_url: channel.author_thumbnail,
|
|
|
|
xml.element("link", rel: "self", href: "#{HOST_URL}#{env.request.resource}")
|
|
|
|
author: channel.author,
|
|
|
|
end
|
|
|
|
author_url: "#{HOST_URL}/channel/#{channel.ucid}",
|
|
|
|
|
|
|
|
date_updated: feed_updated,
|
|
|
|
|
|
|
|
date_published: feed_created,
|
|
|
|
|
|
|
|
alt_links: [{
|
|
|
|
|
|
|
|
type: "text/html",
|
|
|
|
|
|
|
|
url: "#{HOST_URL}/channel/#{channel.ucid}",
|
|
|
|
|
|
|
|
}]
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
videos.each do |video|
|
|
|
|
return Invidious::RssAtom.atom_feed_builder(
|
|
|
|
video.to_xml(channel.auto_generated, params, xml)
|
|
|
|
env, videos, "channel/#{channel.ucid}", properties
|
|
|
|
end
|
|
|
|
)
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
def self.rss_private(env)
|
|
|
|
def self.rss_private(env)
|
|
|
@ -245,20 +238,20 @@ module Invidious::Routes::Feeds
|
|
|
|
|
|
|
|
|
|
|
|
videos, notifications = get_subscription_feed(user, max_results, page)
|
|
|
|
videos, notifications = get_subscription_feed(user, max_results, page)
|
|
|
|
|
|
|
|
|
|
|
|
XML.build(indent: " ", encoding: "UTF-8") do |xml|
|
|
|
|
# Generate Atom feed
|
|
|
|
xml.element("feed", "xmlns:yt": "http://www.youtube.com/xml/schemas/2015",
|
|
|
|
|
|
|
|
"xmlns:media": "http://search.yahoo.com/mrss/", xmlns: "http://www.w3.org/2005/Atom",
|
|
|
|
|
|
|
|
"xml:lang": "en-US") do
|
|
|
|
|
|
|
|
xml.element("link", "type": "text/html", rel: "alternate", href: "#{HOST_URL}/feed/subscriptions")
|
|
|
|
|
|
|
|
xml.element("link", "type": "application/atom+xml", rel: "self",
|
|
|
|
|
|
|
|
href: "#{HOST_URL}#{env.request.resource}")
|
|
|
|
|
|
|
|
xml.element("title") { xml.text translate(locale, "Invidious Private Feed for `x`", user.email) }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(notifications + videos).each do |video|
|
|
|
|
properties = Invidious::RssAtom::AtomProperties.new(
|
|
|
|
video.to_xml(locale, params, xml)
|
|
|
|
title: translate(locale, "Invidious Private Feed for `x`", user.email),
|
|
|
|
end
|
|
|
|
author: user.email,
|
|
|
|
end
|
|
|
|
alt_links: [{
|
|
|
|
end
|
|
|
|
type: "text/html",
|
|
|
|
|
|
|
|
url: "#{HOST_URL}/feed/subscriptions",
|
|
|
|
|
|
|
|
}]
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return Invidious::RssAtom.atom_feed_builder(
|
|
|
|
|
|
|
|
env, (notifications + videos), "subscriptions/#{user.email}", properties
|
|
|
|
|
|
|
|
)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
def self.rss_playlist(env)
|
|
|
|
def self.rss_playlist(env)
|
|
|
@ -276,23 +269,20 @@ module Invidious::Routes::Feeds
|
|
|
|
if playlist = Invidious::Database::Playlists.select(id: plid)
|
|
|
|
if playlist = Invidious::Database::Playlists.select(id: plid)
|
|
|
|
videos = get_playlist_videos(playlist, offset: 0)
|
|
|
|
videos = get_playlist_videos(playlist, offset: 0)
|
|
|
|
|
|
|
|
|
|
|
|
return XML.build(indent: " ", encoding: "UTF-8") do |xml|
|
|
|
|
# Generate Atom feed
|
|
|
|
xml.element("feed", "xmlns:yt": "http://www.youtube.com/xml/schemas/2015",
|
|
|
|
|
|
|
|
"xmlns:media": "http://search.yahoo.com/mrss/", xmlns: "http://www.w3.org/2005/Atom",
|
|
|
|
|
|
|
|
"xml:lang": "en-US") do
|
|
|
|
|
|
|
|
xml.element("link", rel: "self", href: "#{HOST_URL}#{env.request.resource}")
|
|
|
|
|
|
|
|
xml.element("id") { xml.text "iv:playlist:#{plid}" }
|
|
|
|
|
|
|
|
xml.element("iv:playlistId") { xml.text plid }
|
|
|
|
|
|
|
|
xml.element("title") { xml.text playlist.title }
|
|
|
|
|
|
|
|
xml.element("link", rel: "alternate", href: "#{HOST_URL}/playlist?list=#{plid}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
xml.element("author") do
|
|
|
|
properties = Invidious::RssAtom::AtomProperties.new(
|
|
|
|
xml.element("name") { xml.text playlist.author }
|
|
|
|
title: playlist.title,
|
|
|
|
end
|
|
|
|
author: playlist.author,
|
|
|
|
|
|
|
|
alt_links: [{
|
|
|
|
|
|
|
|
type: "text/html",
|
|
|
|
|
|
|
|
url: "#{HOST_URL}/playlist?list=#{plid}",
|
|
|
|
|
|
|
|
}]
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
videos.each &.to_xml(xml)
|
|
|
|
return Invidious::RssAtom.atom_feed_builder(
|
|
|
|
end
|
|
|
|
env, videos, "playlist/#{plid}", properties
|
|
|
|
end
|
|
|
|
)
|
|
|
|
else
|
|
|
|
else
|
|
|
|
haltf env, status_code: 404
|
|
|
|
haltf env, status_code: 404
|
|
|
|
end
|
|
|
|
end
|
|
|
|