Update rss_feed plugin from core repo

This commit is contained in:
Ryan Kulp
2026-06-08 07:47:18 -04:00
parent 8579a5e6a2
commit edd7eecafc
8 changed files with 158 additions and 0 deletions
+1
View File
@@ -24,6 +24,7 @@ community Recipes:
- [Nano Banana Dashboard](/lib/nano_banana_dashboard)
- [Notion](/lib/notion)
- [Parcel](/lib/parcel)
- [Rss Feed](/lib/rss_feed)
- [Shopify](/lib/shopify)
- [Stock Price](/lib/stock_price)
- [Tempest Weather Station](/lib/tempest_weather_station)
+100
View File
@@ -0,0 +1,100 @@
module Plugins
class RssFeed < Base
def locals
{ rss_feed: }
end
private
def rss_feed
feed = process_feed
feed.is_a?(Array) ? feed : [feed]
end
def process_feed
validate_uri(settings['url'])
response = fetch(settings['url'].strip, headers:)
raise InvalidURL unless response.respond_to?(:code) && response.respond_to?(:body)
raise InvalidURL if response.code.to_i >= 400
return content_error(StandardError.new("Response Code: #{response.code}")) if response.code != 200
return content_error(StandardError.new("No Content")) if response.body.nil? || response.body.empty?
feed = RSS::Parser.parse(response.body, validate: false)
if layout == 'featured'
normalize_feed(feed&.items&.first)
elsif layout == 'list'
feed&.items&.[](0..7)&.map do |post|
normalize_feed(post, strip_to_text: true)
end
end
rescue OpenURI::HTTPError, RSS::NotWellFormedError, RSS::TooMuchTagError => e
content_error(e)
rescue InvalidURL, URI::InvalidURIError, OpenSSL::SSL::SSLError => e
handle_erroring_state(e)
content_error(e)
end
def normalize_feed(post, strip_to_text: false)
content = if post.is_a?(RSS::Atom::Feed::Entry)
{
title: post&.title&.content,
content: post&.summary&.content || post&.content&.to_s
}.compact
else
{
title: post&.title,
content: post&.content_encoded || post&.description
}.compact
end
return content_error(StandardError.new("No Content")) if content.empty?
if strip_to_text
strip_html(content)
else
dither_image(content)
end
end
def validate_uri(url)
raise InvalidURL unless url =~ URI::DEFAULT_PARSER.make_regexp
end
# added 2025-01-08 per customer observation that some rss feeds prevent fetches without user-agent present
def headers
{
'user-agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/601.3.9 (KHTML, like Gecko) Version/9.0.2 Safari/601.3.9'
}
end
def dither_image(feed)
content = feed[:content]
return feed if content.nil?
content.gsub!(%r{<img(.*?)/?>}, '<img\1 class="image-dither w-full h-auto object-contain block mx-auto" />')
feed[:content] = content
feed
end
# Make content in the list view plaintext so we don't overflow.
def strip_html(feed)
content = feed[:content]
return feed if content.nil?
plain_text = ActionController::Base.helpers.strip_tags(content)
feed[:content] = plain_text.squish.truncate(200)
feed
end
def content_error(error)
{
title: 'Error while parsing RSS content',
content: "Message: #{error&.message}"
}
end
def layout = settings['layout'] || 'featured'
end
end
+7
View File
@@ -0,0 +1,7 @@
<div class="view view--full">
<div class="layout">
<%= render "plugins/rss_feed/shared/feed", rss_feed: rss_feed %>
</div>
<%= render "plugins/rss_feed/shared/title_bar", instance_name: instance_name %>
</div>
@@ -0,0 +1,7 @@
<div class="view view--half_horizontal">
<div class="layout">
<%= render "plugins/rss_feed/shared/feed", rss_feed: rss_feed %>
</div>
<%= render "plugins/rss_feed/shared/title_bar", instance_name: instance_name %>
</div>
@@ -0,0 +1,7 @@
<div class="view view--half_vertical">
<div class="layout">
<%= render "plugins/rss_feed/shared/feed", rss_feed: rss_feed %>
</div>
<%= render "plugins/rss_feed/shared/title_bar", instance_name: instance_name %>
</div>
+7
View File
@@ -0,0 +1,7 @@
<div class="view view--quadrant">
<div class="layout">
<%= render "plugins/rss_feed/shared/feed", rss_feed: rss_feed %>
</div>
<%= render "plugins/rss_feed/shared/title_bar", instance_name: instance_name %>
</div>
+24
View File
@@ -0,0 +1,24 @@
<div class="columns" data-overflow-max-cols="1">
<div class="column">
<% if rss_feed.count == 1 %>
<div class="richtext richtext--center gap">
<style>.content img { max-width: 100% }</style>
<span class="title lg:title--large"><%= rss_feed.first[:title] %></span>
<div class="content lg:content--large" data-content-limiter="true"><%= sanitize(rss_feed.first[:content]) %></div>
</div>
<% else %>
<% rss_feed.each_with_index do |feed, idx| %>
<div class="item">
<div class="meta">
<span class="index"><%= idx + 1 %></span>
</div>
<div class="content">
<span class="title title--small lg:title--base"><%= simple_format(render_markdown(feed[:title])) %></span>
<p class="description lg:description--large" data-clamp="2"><%= sanitize(feed[:content]) %></p>
</div>
</div>
<% end %>
<% end %>
</div>
</div>
@@ -0,0 +1,5 @@
<div class="title_bar">
<%= image_tag plugin_image_path("rss--render.svg"), class: "image", alt: "" %>
<span class="title">RSS Feed</span>
<span class="instance"><%= instance_name %></span>
</div>