Martin Brennan 1cdd3fd708
FIX: Various bugs from 2024 rewind (#29)
* Use post excerpt for best posts to avoid giant posts
  ruining it
* Make sure short emojis (e.g. `😂`) render in best posts
  and best topics
* Make images show in best post excerpts (requires core change)
* Fix invite action error, using column that doesn't exist
* Add missing # for top category slugs
* Refactor report service + controller a little to make it easier
  to figure out what went wrong if it fails, and to use the guardian
  user

Copies a couple of fixes from
https://github.com/discourse/discourse-rewind/pull/28 to make
things work locally, the conflicts will be easy to resolve.

**Best topics before**

<img width="977" height="712" alt="image"
src="https://github.com/user-attachments/assets/e120507f-d0d8-44f0-b242-e1056084ef03"
/>


**Best topics after**

<img width="969" height="648" alt="image"
src="https://github.com/user-attachments/assets/dd13f6ac-35df-4e9a-907e-9ed5102843b6"
/>

**Categories before**

<img width="904" height="465" alt="image"
src="https://github.com/user-attachments/assets/0d15e73d-3534-4836-b776-2c97381e58ef"
/>


**Categories after**

<img width="925" height="466" alt="image"
src="https://github.com/user-attachments/assets/3d6e4eae-32ed-4f11-a4f4-090e4473ebe9"
/>
2025-11-19 09:36:08 +10:00

90 lines
2.1 KiB
Ruby

# frozen_string_literal: true
module DiscourseRewind
# Service responsible to fetch a rewind for a username/year.
#
# @example
# ::DiscourseRewind::Rewind::Fetch.call(
# guardian: guardian
# )
#
class FetchReports
include Service::Base
# @!method self.call(guardian:, params:)
# @param [Guardian] guardian
# @param [Hash] params
# @option params [Integer] :year of the rewind
# @option params [Integer] :username of the rewind
# @return [Service::Base::Context]
CACHE_DURATION = Rails.env.development? ? 10.seconds : 5.minutes
# order matters
REPORTS = [
Action::TopWords,
Action::ReadingTime,
Action::Reactions,
Action::Fbff,
Action::MostViewedTags,
Action::MostViewedCategories,
Action::BestTopics,
Action::BestPosts,
Action::ActivityCalendar,
Action::TimeOfDayActivity,
Action::NewUserInteractions,
Action::ChatUsage,
Action::AiUsage,
Action::FavoriteGifs,
Action::Assignments,
Action::Invites,
]
model :year
model :date
model :reports
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_reports(date:, guardian:, year:)
key = "rewind:#{guardian.user.username}:#{year}"
reports = Discourse.redis.get(key)
if !reports
reports =
REPORTS.map { |report| report.call(date:, user: guardian.user, guardian:) }.compact
Discourse.redis.setex(key, CACHE_DURATION, MultiJson.dump(reports))
else
reports = MultiJson.load(reports, symbolize_keys: true)
end
reports
end
end
end