From 56f1b6877139fadce5432e2244bf8dbc514f016f Mon Sep 17 00:00:00 2001 From: Samantaz Fox Date: Tue, 16 Nov 2021 21:23:13 +0100 Subject: [PATCH] Use 'atom_feed_builder()' to build Atom feeds --- src/invidious/helpers/serialized_yt_data.cr | 17 ++-- src/invidious/routes/feeds.cr | 96 ++++++++++----------- 2 files changed, 52 insertions(+), 61 deletions(-) diff --git a/src/invidious/helpers/serialized_yt_data.cr b/src/invidious/helpers/serialized_yt_data.cr index bfbc237c..4d41a964 100644 --- a/src/invidious/helpers/serialized_yt_data.cr +++ b/src/invidious/helpers/serialized_yt_data.cr @@ -17,20 +17,13 @@ struct SearchVideo query_params["v"] = self.id xml.element("entry") do - xml.element("id") { xml.text "yt:video:#{self.id}" } - xml.element("yt:videoId") { xml.text self.id } - xml.element("yt:channelId") { xml.text self.ucid } + xml.element("id") { xml.text self.id } xml.element("title") { xml.text self.title } xml.element("link", rel: "alternate", href: "#{HOST_URL}/watch?#{query_params}") xml.element("author") do - if auto_generated - xml.element("name") { xml.text self.author } - xml.element("uri") { xml.text "#{HOST_URL}/channel/#{self.ucid}" } - else - xml.element("name") { xml.text author } - xml.element("uri") { xml.text "#{HOST_URL}/channel/#{ucid}" } - end + xml.element("name") { xml.text self.author } + xml.element("uri") { xml.text "#{HOST_URL}/channel/#{self.ucid}" } end xml.element("content", type: "xhtml") do @@ -39,7 +32,9 @@ struct SearchVideo xml.element("img", src: "#{HOST_URL}/vi/#{self.id}/mqdefault.jpg") end - xml.element("p", style: "word-break:break-word;white-space:pre-wrap") { xml.text html_to_content(self.description_html) } + xml.element("p", style: "white-space:pre-wrap") do + xml.text html_to_content(self.description_html) + end end end diff --git a/src/invidious/routes/feeds.cr b/src/invidious/routes/feeds.cr index fd8c25ce..cc97ea65 100644 --- a/src/invidious/routes/feeds.cr +++ b/src/invidious/routes/feeds.cr @@ -144,8 +144,6 @@ module Invidious::Routes::Feeds ucid = env.params.url["ucid"] - params = HTTP::Params.parse(env.params.query["params"]? || "") - begin channel = get_about_info(ucid, locale) rescue ex : ChannelRedirect @@ -157,12 +155,13 @@ module Invidious::Routes::Feeds response = YT_POOL.client &.get("/feeds/videos.xml?channel_id=#{channel.ucid}") rss = XML.parse_html(response.body) + updated = [] of String videos = rss.xpath_nodes("//feed/entry").map do |entry| video_id = entry.xpath_node("videoid").not_nil!.content title = entry.xpath_node("title").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 ucid = entry.xpath_node("channelid").not_nil!.content @@ -185,27 +184,27 @@ module Invidious::Routes::Feeds }) end - XML.build(indent: " ", encoding: "UTF-8") do |xml| - 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 "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}") + feed_created = rss.xpath_node("//feed/published").not_nil!.content + feed_updated = updated.size > 0 ? updated[0] : feed_created - xml.element("author") do - xml.element("name") { xml.text channel.author } - xml.element("uri") { xml.text "#{HOST_URL}/channel/#{channel.ucid}" } - end + # Generate Atom feed - videos.each do |video| - video.to_xml(channel.auto_generated, params, xml) - end - end - end + alt_links = [{ + type: "text/html", + url: "#{HOST_URL}/channel/#{channel.ucid}", + }] + + return Invidious::RssAtom.atom_feed_builder( + env, videos, + id: "channel/#{channel.ucid}", + title: "", # Use channel author name + icon_url: channel.author_thumbnail, + author: channel.author, + author_url: "#{HOST_URL}/channel/#{channel.ucid}", + date_updated: feed_updated, + date_published: feed_created, + alt_links: alt_links + ) end def self.rss_private(env) @@ -236,20 +235,20 @@ module Invidious::Routes::Feeds videos, notifications = get_subscription_feed(user, max_results, page) - XML.build(indent: " ", encoding: "UTF-8") do |xml| - 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) } + # Generate Atom feed - (notifications + videos).each do |video| - video.to_xml(locale, params, xml) - end - end - end + alt_links = [{ + type: "text/html", + url: "#{HOST_URL}/feed/subscriptions", + }] + + return Invidious::RssAtom.atom_feed_builder( + env, (notifications + videos), + id: "subscriptions/#{user.email}", + title: translate(locale, "Invidious Private Feed for `x`", user.email), + author: user.email, + alt_links: alt_links, + ) end def self.rss_playlist(env) @@ -267,23 +266,20 @@ module Invidious::Routes::Feeds if playlist = Invidious::Database::Playlists.select(id: plid) videos = get_playlist_videos(playlist, offset: 0, locale: locale) - return XML.build(indent: " ", encoding: "UTF-8") do |xml| - 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}") + # Generate Atom feed - xml.element("author") do - xml.element("name") { xml.text playlist.author } - end + alt_links = [{ + type: "text/html", + url: "#{HOST_URL}/playlist?list=#{plid}", + }] - videos.each &.to_xml(xml) - end - end + return Invidious::RssAtom.atom_feed_builder( + env, videos, + id: "playlist/#{plid}", + title: playlist.title, + author: playlist.author, + alt_links: alt_links + ) else haltf env, status_code: 404 end