2025-11-26 15:12:59 -03:00

93 lines
2.4 KiB
Ruby

# frozen_string_literal: true
module DiscourseRewind
# Service responsible to fetch a single report by index.
#
# @example
# ::DiscourseRewind::FetchReport.call(
# guardian: guardian,
# index: 3
# )
#
class FetchReport
include Service::Base
# @!method self.call(guardian:, params:)
# @param [Guardian] guardian
# @param [Hash] params
# @option params [Integer] :index the report index
# @return [Service::Base::Context]
CACHE_DURATION = Rails.env.development? ? 10.seconds : 5.minutes
model :year
model :date
model :report_class
model :report
private
def fetch_year
current_date = Time.zone.now
current_month = current_date.month
current_year = current_date.year
case current_month
when 1
current_year - 1
when 12
current_year
else
# Otherwise it's impossible to test in browser unless you're
# in December or January
if Rails.env.development?
current_year
else
false
end
end
end
def fetch_date(params:, year:)
Date.new(year).all_year
end
def fetch_report_class(date:, guardian:, year:, params:)
# Use the same cached all_reports list as FetchReports
# If not cached, generate it now
key = "rewind:#{guardian.user.username}:#{year}:all_reports"
cached_list = Discourse.redis.get(key)
all_reports =
if cached_list
MultiJson.load(cached_list, symbolize_keys: true)
else
# Generate all reports and cache them
reports =
FetchReports::REPORTS.filter_map do |report_class|
begin
report_class.call(date:, user: guardian.user, guardian:)
rescue => e
Rails.logger.error("Failed to generate report #{report_class.name}: #{e.message}")
nil
end
end
Discourse.redis.setex(key, CACHE_DURATION, MultiJson.dump(reports))
reports
end
# Access index from params data object (params.index) or hash (params[:index])
index = (params[:index] || params.index).to_i
return false if index < 0 || index >= all_reports.length
all_reports[index]
end
def fetch_report(report_class:)
# Report is already generated and cached in the all_reports list
report_class
end
end
end