mirror of
https://github.com/usetrmnl/plugins.git
synced 2026-08-13 14:26:58 -07:00
Update statuspage plugin from core repo
This commit is contained in:
@@ -26,6 +26,7 @@ community Recipes:
|
||||
- [Parcel](/lib/parcel)
|
||||
- [RSS Feed](/lib/rss_feed)
|
||||
- [Shopify](/lib/shopify)
|
||||
- [Statuspage](/lib/statuspage)
|
||||
- [Stock Price](/lib/stock_price)
|
||||
- [Tempest Weather Station](/lib/tempest_weather_station)
|
||||
- [Todoist](/lib/todoist)
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
module Plugins
|
||||
class Statuspage < Base
|
||||
|
||||
def locals
|
||||
{ pages: }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# NOTE: only works with pages hosted on statuspage.io
|
||||
def pages
|
||||
content = { 'incidents' => [], 'scheduled' => [] }
|
||||
items.each do |item|
|
||||
next unless item.is_a?(Hash) && item[:date]
|
||||
|
||||
if item[:date] > DateTime.now
|
||||
item[:icon] = 'calendar_star'
|
||||
content['scheduled'] << item
|
||||
else
|
||||
item[:icon] = item[:date] > 24.hours.ago ? 'shield_warning' : 'hexagon'
|
||||
content['incidents'] << item
|
||||
end
|
||||
end
|
||||
|
||||
content
|
||||
end
|
||||
|
||||
# rubocop:disable Security/Open
|
||||
def items
|
||||
page_urls.map do |url|
|
||||
URI.open(url, open_timeout: 5) do |rss|
|
||||
feed = RSS::Parser.parse(rss, validate: false)
|
||||
latest_post = feed&.items&.first
|
||||
|
||||
if latest_post.nil?
|
||||
{
|
||||
content: 'Unsupported status page',
|
||||
site_name: url
|
||||
}
|
||||
elsif latest_post.is_a?(RSS::Atom::Feed::Entry)
|
||||
{
|
||||
title: latest_post&.title&.content,
|
||||
date: latest_post&.published&.content,
|
||||
content: latest_post&.content&.content,
|
||||
site_name: feed&.title&.content
|
||||
}
|
||||
else
|
||||
{
|
||||
title: latest_post&.title,
|
||||
date: latest_post&.pubDate,
|
||||
content: latest_post&.description, # not used, just in case
|
||||
site_name: feed&.channel&.title&.split('Status')&.first&.squish # => 'Prompt.io'
|
||||
}
|
||||
end
|
||||
end
|
||||
rescue OpenURI::HTTPError, RSS::NotWellFormedError, Errno::ENOENT
|
||||
nil
|
||||
rescue URI::InvalidURIError, SocketError, Resolv::ResolvError, Net::OpenTimeout, Net::ReadTimeout,
|
||||
OpenSSL::SSL::SSLError, Errno::EHOSTUNREACH, Errno::ECONNREFUSED, Errno::EPIPE => e
|
||||
handle_erroring_state(e.message)
|
||||
nil
|
||||
rescue RuntimeError => e
|
||||
raise unless e.message.include?('redirection forbidden')
|
||||
|
||||
handle_erroring_state(e.message)
|
||||
nil
|
||||
end.compact
|
||||
end
|
||||
# rubocop:enable Security/Open
|
||||
|
||||
def page_urls
|
||||
line_separated_string_to_array(settings['page_urls']).map do |base_url|
|
||||
next unless base_url.include?('http') # IDEA: extract RssFeed > validate_uri()
|
||||
|
||||
if ['/history.rss', '/feed'].any? { |pattern| base_url.include?(pattern) }
|
||||
base_url
|
||||
else
|
||||
base_url.chomp('/').concat('/history.rss')
|
||||
end
|
||||
end.compact # ignores skipped / malformed URLs
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,5 @@
|
||||
<div class="view view--full">
|
||||
<%= render "plugins/statuspage/shared/layout", pages: pages, always_columns: true, overflow_counter: true, large_text: true %>
|
||||
|
||||
<%= render "plugins/statuspage/shared/title_bar", instance_name: instance_name %>
|
||||
</div>
|
||||
@@ -0,0 +1,5 @@
|
||||
<div class="view view--half_horizontal">
|
||||
<%= render "plugins/statuspage/shared/layout", pages: pages, clamp_details: true, always_columns: true %>
|
||||
|
||||
<%= render "plugins/statuspage/shared/title_bar", instance_name: instance_name %>
|
||||
</div>
|
||||
@@ -0,0 +1,5 @@
|
||||
<div class="view view--half_vertical">
|
||||
<%= render "plugins/statuspage/shared/layout", pages: pages, overflow_counter: true %>
|
||||
|
||||
<%= render "plugins/statuspage/shared/title_bar", instance_name: instance_name %>
|
||||
</div>
|
||||
@@ -0,0 +1,5 @@
|
||||
<div class="view view--quadrant">
|
||||
<%= render "plugins/statuspage/shared/layout", pages: pages %>
|
||||
|
||||
<%= render "plugins/statuspage/shared/title_bar", instance_name: instance_name %>
|
||||
</div>
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="<%= local_assigns[:classes] || '' %>" width="32" height="32" fill="currentColor" viewBox="0 0 256 256"><path d="M208,32H184V24a8,8,0,0,0-16,0v8H88V24a8,8,0,0,0-16,0v8H48A16,16,0,0,0,32,48V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V48A16,16,0,0,0,208,32Zm0,176H48V48H72v8a8,8,0,0,0,16,0V48h80v8a8,8,0,0,0,16,0V48h24V208Zm-31.38-94.36-29.84-2.31-11.43-26.5a8,8,0,0,0-14.7,0l-11.43,26.5-29.84,2.31a8,8,0,0,0-4.47,14.14l22.52,18.59-6.86,27.71a8,8,0,0,0,11.82,8.81L128,167.82l25.61,15.07a8,8,0,0,0,11.82-8.81l-6.86-27.71,22.52-18.59a8,8,0,0,0-4.47-14.14Zm-32.11,23.6a8,8,0,0,0-2.68,8.09l3.5,14.12-13.27-7.81a8,8,0,0,0-8.12,0l-13.27,7.81,3.5-14.12a8,8,0,0,0-2.68-8.09l-11.11-9.18,14.89-1.15a8,8,0,0,0,6.73-4.8l6-13.92,6,13.92a8,8,0,0,0,6.73,4.8l14.89,1.15Z"></path></svg>
|
||||
|
After Width: | Height: | Size: 814 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="<%= local_assigns[:classes] || '' %>" width="32" height="32" fill="currentColor" viewBox="0 0 256 256"><path d="M223.68,66.15,135.68,18h0a15.88,15.88,0,0,0-15.36,0l-88,48.17a16,16,0,0,0-8.32,14v95.64a16,16,0,0,0,8.32,14l88,48.17a15.88,15.88,0,0,0,15.36,0l88-48.17a16,16,0,0,0,8.32-14V80.18A16,16,0,0,0,223.68,66.15ZM216,175.82,128,224,40,175.82V80.18L128,32h0l88,48.17Z"></path></svg>
|
||||
|
After Width: | Height: | Size: 432 B |
@@ -0,0 +1,44 @@
|
||||
<% groups = (pages || {}).to_a.first(2) %>
|
||||
<% always_columns = local_assigns[:always_columns] == true %>
|
||||
<% large_text = local_assigns[:large_text] == true %>
|
||||
<% heading_label_class = large_text ? "label lg:label--large" : "label" %>
|
||||
<% title_class = large_text ? "title title--small lg:title--base" : "title title--small" %>
|
||||
|
||||
<div class="layout">
|
||||
<div class="flex flex--row flex--stretch-y h--full w--full <%= 'portrait:flex--col portrait:gap--none' unless always_columns %>">
|
||||
<% groups.each_with_index do |(type, items), index| %>
|
||||
<% section_items = Array(items) %>
|
||||
<div class="grow basis--0 w--min-0 <%= 'portrait:h--[50cqh] portrait:grow-0 portrait:shrink-0 portrait:basis--auto portrait:w--full' unless always_columns %> <%= 'portrait:pt--2' if !always_columns && index.positive? %>">
|
||||
<div class="flex flex--col flex--top h--full w--full">
|
||||
<div class="item">
|
||||
<span class="<%= heading_label_class %>"><%= type.to_s.titleize %></span>
|
||||
</div>
|
||||
|
||||
<div class="stretch-y w--full">
|
||||
<div class="flex flex--col gap h--full" data-overflow="true" data-overflow-max-height="auto" data-overflow-counter="<%= (local_assigns[:overflow_counter] == true).to_s %>">
|
||||
<% section_items.each do |item| %>
|
||||
<div class="item">
|
||||
<div class="meta"></div>
|
||||
<div class="content">
|
||||
<div class="flex flex--row flex--center-y">
|
||||
<%= render "plugins/statuspage/shared/#{item[:icon]}", classes: (local_assigns[:icon_classes] || "w--6 h--6") %>
|
||||
<span class="<%= title_class %>"><%= item[:site_name] %></span>
|
||||
</div>
|
||||
<span class="label label--small"<% if local_assigns[:clamp_details] %> data-clamp="1"<% end %>>
|
||||
<% if type.to_s == 'scheduled' %>
|
||||
Scheduled: <%= l(item[:date].to_date, format: "%B %d, %Y") %>
|
||||
<% elsif type.to_s == 'incidents' %>
|
||||
Last Incident: <%= localized_time_ago(item[:date]) %>
|
||||
<% end %>
|
||||
</span>
|
||||
<span class="label label--small"<% if local_assigns[:clamp_details] %> data-clamp="1"<% end %>><%= item[:title] %></span>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="<%= local_assigns[:classes] || '' %>" width="32" height="32" fill="currentColor" viewBox="0 0 256 256"><path d="M120,136V96a8,8,0,0,1,16,0v40a8,8,0,0,1-16,0Zm8,48a12,12,0,1,0-12-12A12,12,0,0,0,128,184ZM224,56v56c0,52.72-25.52,84.67-46.93,102.19-23.06,18.86-46,25.27-47,25.53a8,8,0,0,1-4.2,0c-1-.26-23.91-6.67-47-25.53C57.52,196.67,32,164.72,32,112V56A16,16,0,0,1,48,40H208A16,16,0,0,1,224,56Zm-16,0L48,56l0,56c0,37.3,13.82,67.51,41.07,89.81A128.25,128.25,0,0,0,128,223.62a129.3,129.3,0,0,0,39.41-22.2C194.34,179.16,208,149.07,208,112Z"></path></svg>
|
||||
|
After Width: | Height: | Size: 597 B |
@@ -0,0 +1,5 @@
|
||||
<div class="title_bar">
|
||||
<%= image_tag plugin_image_path("statuspage--render.svg"), class: "image image--adaptive", alt: "Statuspage" %>
|
||||
<h1 class="title">Statuspage</h1>
|
||||
<span class="instance"><%= instance_name %></span>
|
||||
</div>
|
||||
Reference in New Issue
Block a user