0
0
Fork 1
Spiegel von https://github.com/paviliondev/discourse-custom-wizard.git synchronisiert 2024-11-29 12:20:27 +01:00
discourse-custom-wizard/lib/custom_wizard/notice.rb

233 Zeilen
6,2 KiB
Ruby

2021-09-24 11:58:42 +02:00
# frozen_string_literal: true
class CustomWizard::Notice
include ActiveModel::Serialization
2021-10-05 14:54:06 +02:00
PLUGIN_STATUS_DOMAINS = {
2021-10-13 13:32:49 +02:00
"tests-passed" => "plugins.thepavilion.io",
"stable" => "stable.plugins.thepavilion.io"
2021-10-05 14:54:06 +02:00
}
2021-10-13 13:32:49 +02:00
SUBSCRIPTION_MESSAGES_DOMAIN = "test.thepavilion.io"
2021-10-05 14:54:06 +02:00
LOCALHOST_DOMAIN = "localhost:3000"
2021-09-24 11:58:42 +02:00
PLUGIN_STATUSES_TO_WARN = %w(incompatible tests_failing)
2021-10-05 14:54:06 +02:00
CHECK_PLUGIN_STATUS_ON_BRANCH = %w(tests-passed main stable)
2021-09-24 11:58:42 +02:00
attr_reader :id,
:message,
:type,
:created_at
attr_accessor :retrieved_at,
2021-10-05 14:54:06 +02:00
:updated_at,
2021-09-24 11:58:42 +02:00
:dismissed_at,
:expired_at
def initialize(attrs)
@id = Digest::SHA1.hexdigest(attrs[:message])
@message = attrs[:message]
@type = attrs[:type].to_i
@created_at = attrs[:created_at]
2021-10-05 14:54:06 +02:00
@updated_at = attrs[:updated_at]
2021-09-24 11:58:42 +02:00
@retrieved_at = attrs[:retrieved_at]
@dismissed_at = attrs[:dismissed_at]
@expired_at = attrs[:expired_at]
end
def dismiss
if dismissable?
self.dismissed_at = Time.now
self.save
end
end
def expire
self.expired_at = Time.now
self.save
end
def expired?
expired_at.present?
end
def dismissed?
dismissed_at.present?
end
def dismissable?
true
end
def save
attrs = {
expired_at: expired_at,
created_at: created_at,
message: message,
type: type
}
if current = self.class.find(self.id)
attrs[:dismissed_at] = current.dismissed_at || self.dismissed_at
end
self.class.store(id, attrs)
end
def self.types
@types ||= Enum.new(
info: 0,
2021-10-05 14:54:06 +02:00
plugin_status_warning: 1,
plugin_status_connection_error: 2,
subscription_messages_connection_error: 3
2021-09-24 11:58:42 +02:00
)
end
def self.update(skip_subscription: false, skip_plugin: false)
notices = []
if !skip_subscription
2021-10-05 14:54:06 +02:00
subscription_messages = request(:subscription_messages)
2021-09-24 11:58:42 +02:00
if subscription_messages.present?
subscription_notices = convert_subscription_messages_to_notices(subscription_messages[:messages])
notices.push(*subscription_notices)
end
end
2021-10-05 14:54:06 +02:00
if !skip_plugin && request_plugin_status?
plugin_status = request(:plugin_status)
2021-09-24 11:58:42 +02:00
if plugin_status.present? && plugin_status[:status].present? && plugin_status[:status].is_a?(Hash)
plugin_notice = convert_plugin_status_to_notice(plugin_status[:status])
notices.push(plugin_notice) if plugin_notice
end
end
notices.each do |notice_data|
notice = new(notice_data)
notice.retrieved_at = Time.now
notice.save
end
end
def self.convert_subscription_messages_to_notices(messages)
messages.map do |message|
{
message: message[:message],
type: types[message[:type].to_sym],
created_at: message[:created_at],
expired_at: message[:expired_at]
}
end
end
def self.convert_plugin_status_to_notice(plugin_status)
notice = nil
if PLUGIN_STATUSES_TO_WARN.include?(plugin_status[:status])
notice = {
2021-10-07 15:19:19 +02:00
message: I18n.t('wizard.notice.compatibility_issue', domain: plugin_status_domain),
2021-10-05 14:54:06 +02:00
type: types[:plugin_status_warning],
2021-09-24 11:58:42 +02:00
created_at: plugin_status[:status_changed_at]
}
else
2021-10-05 14:54:06 +02:00
expire_notices(types[:plugin_status_warning])
2021-09-24 11:58:42 +02:00
end
notice
end
2021-10-05 14:54:06 +02:00
def self.notify_connection_errors(connection_type_key)
domain = self.send("#{connection_type_key.to_s}_domain")
2021-10-07 15:19:19 +02:00
message = I18n.t("wizard.notice.#{connection_type_key.to_s}.connection_error_limit", domain: domain)
2021-10-05 14:54:06 +02:00
notices = list(type: types[:connection_error], message: message)
if notices.any?
notice = notices.first
notice.updated_at = Time.now
notice.save
else
notice = new(
message: message,
type: types["#{connection_type_key}_connection_error".to_sym],
created_at: Time.now
)
notice.save
end
end
def self.expire_notices(type)
list(type: type).each(&:expire)
end
def self.request_plugin_status?
CHECK_PLUGIN_STATUS_ON_BRANCH.include?(Discourse.git_branch) || Rails.env.test? || Rails.env.development?
end
2021-09-24 11:58:42 +02:00
def self.subscription_messages_domain
2021-10-05 14:54:06 +02:00
(Rails.env.test? || Rails.env.development?) ? LOCALHOST_DOMAIN : SUBSCRIPTION_MESSAGES_DOMAIN
2021-09-24 11:58:42 +02:00
end
def self.subscription_messages_url
"http://#{subscription_messages_domain}/subscription-server/messages.json"
end
def self.plugin_status_domain
2021-10-05 14:54:06 +02:00
return LOCALHOST_DOMAIN if (Rails.env.test? || Rails.env.development?)
PLUGIN_STATUS_DOMAINS[Discourse.git_branch]
2021-09-24 11:58:42 +02:00
end
def self.plugin_status_url
"http://#{plugin_status_domain}/plugin-manager/status/discourse-custom-wizard"
end
2021-10-05 14:54:06 +02:00
def self.request(type)
url = self.send("#{type.to_s}_url")
2021-09-24 11:58:42 +02:00
response = Excon.get(url)
2021-10-05 14:54:06 +02:00
connection_error = CustomWizard::Notice::ConnectionError.new(type)
2021-09-24 11:58:42 +02:00
if response.status == 200
2021-10-05 14:54:06 +02:00
connection_error.expire!
expire_notices(types["#{type}_connection_error".to_sym])
2021-09-24 11:58:42 +02:00
begin
data = JSON.parse(response.body).deep_symbolize_keys
rescue JSON::ParserError
return nil
end
2021-10-05 14:54:06 +02:00
2021-09-24 11:58:42 +02:00
data
else
2021-10-05 14:54:06 +02:00
connection_error.create!
notify_connection_errors(type) if connection_error.reached_limit?
2021-09-24 11:58:42 +02:00
nil
end
end
def self.namespace
"#{CustomWizard::PLUGIN_NAME}_notice"
end
def self.find(id)
raw = PluginStore.get(namespace, id)
new(raw.symbolize_keys) if raw.present?
end
def self.store(id, raw_notice)
PluginStore.set(namespace, id, raw_notice)
end
2021-10-05 14:54:06 +02:00
def self.list_query(type: nil, message: nil, include_recently_expired: false)
2021-09-24 11:58:42 +02:00
query = PluginStoreRow.where(plugin_name: namespace)
2021-10-05 14:54:06 +02:00
query = query.where("(value::json->>'expired_at') IS NULL#{include_recently_expired ? " OR (value::json->>'expired_at')::date > now()::date - 1" : ""}")
2021-09-24 11:58:42 +02:00
query = query.where("(value::json->>'type')::integer = ?", type) if type
2021-10-07 15:19:19 +02:00
query = query.where("(value::json->>'message')::text = ?", message) if message
2021-09-24 11:58:42 +02:00
query.order("value::json->>'created_at' DESC")
end
2021-10-05 14:54:06 +02:00
def self.list(type: nil, message: nil, include_recently_expired: false)
list_query(type: type, message: message, include_recently_expired: include_recently_expired)
2021-09-24 11:58:42 +02:00
.map { |r| self.new(JSON.parse(r.value).symbolize_keys) }
end
end