mastodon/app/controllers/api/v1/donation_campaigns_controller.rb

87 lines
1.9 KiB
Ruby

# frozen_string_literal: true
class Api::V1::DonationCampaignsController < Api::BaseController
before_action :require_user!
STOPLIGHT_COOL_OFF_TIME = 60
STOPLIGHT_FAILURE_THRESHOLD = 10
def index
return head 204 if api_url.blank?
json = from_cache
return render json: json if json.present?
campaign = fetch_campaign
return head 204 if campaign.nil?
save_to_cache!(campaign)
render json: campaign
end
private
def api_url
Rails.configuration.x.donation_campaigns.api_url
end
def seed
@seed ||= Random.new(current_account.id).rand(100)
end
def from_cache
key = Rails.cache.read(request_key, raw: true)
return if key.blank?
campaign = Rails.cache.read("donation_campaign:#{key}", raw: true)
JSON.parse(campaign) if campaign.present?
end
def save_to_cache!(campaign)
return if campaign.blank?
Rails.cache.write_multi(
{
request_key => campaign_key(campaign),
"donation_campaign:#{campaign_key(campaign)}" => campaign.to_json,
},
expires_in: 1.hour,
raw: true
)
end
def fetch_campaign
stoplight_wrapper.run do
url = Addressable::URI.parse(api_url)
url.query_values = { platform: 'web', seed: seed, locale: locale, environment: Rails.configuration.x.donation_campaigns.environment }.compact
Request.new(:get, url.to_s).perform do |res|
return JSON.parse(res.body_with_limit) if res.code == 200
end
end
rescue *Mastodon::HTTP_CONNECTION_ERRORS, Oj::ParseError
nil
end
def stoplight_wrapper
Stoplight(
'donation_campaigns',
cool_off_time: STOPLIGHT_COOL_OFF_TIME,
threshold: STOPLIGHT_FAILURE_THRESHOLD
)
end
def request_key
"donation_campaign_request:#{seed}:#{locale}"
end
def campaign_key(campaign)
"#{campaign['id']}:#{campaign['locale']}"
end
def locale
I18n.locale.to_s
end
end