2024-12-13 10:48:20 -03:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
# Forum Best Friend Forever ranking
|
|
|
|
# Score is informative only, do not show in UI
|
|
|
|
module DiscourseRewind
|
2024-12-13 17:00:17 +01:00
|
|
|
class Rewind::Action::Fbff < Rewind::Action::BaseReport
|
2025-01-09 17:55:58 +01:00
|
|
|
MAX_SUMMARY_RESULTS ||= 50
|
|
|
|
LIKE_SCORE ||= 1
|
|
|
|
REPLY_SCORE ||= 10
|
2024-12-13 10:48:20 -03:00
|
|
|
|
|
|
|
def call
|
|
|
|
most_liked_users =
|
|
|
|
like_query(date)
|
|
|
|
.where(acting_user_id: user.id)
|
|
|
|
.group(:user_id)
|
|
|
|
.order("COUNT(*) DESC")
|
|
|
|
.limit(MAX_SUMMARY_RESULTS)
|
|
|
|
.pluck("user_actions.user_id, COUNT(*)")
|
|
|
|
.map { |user_id, count| { user_id => count } }
|
|
|
|
.reduce({}, :merge)
|
|
|
|
|
|
|
|
most_liked_by_users =
|
|
|
|
like_query(date)
|
|
|
|
.where(user: user)
|
|
|
|
.group(:acting_user_id)
|
|
|
|
.order("COUNT(*) DESC")
|
|
|
|
.limit(MAX_SUMMARY_RESULTS)
|
|
|
|
.pluck("acting_user_id, COUNT(*)")
|
|
|
|
.map { |acting_user_id, count| { acting_user_id => count } }
|
|
|
|
.reduce({}, :merge)
|
|
|
|
|
|
|
|
users_who_most_replied_me =
|
|
|
|
post_query(user, date)
|
|
|
|
.where(posts: { user_id: user.id })
|
|
|
|
.group("replies.user_id")
|
|
|
|
.order("COUNT(*) DESC")
|
|
|
|
.limit(MAX_SUMMARY_RESULTS)
|
|
|
|
.pluck("replies.user_id, COUNT(*)")
|
|
|
|
.map { |user_id, count| { user_id => count } }
|
|
|
|
.reduce({}, :merge)
|
|
|
|
|
|
|
|
users_i_most_replied =
|
|
|
|
post_query(user, date)
|
|
|
|
.where("replies.user_id = ?", user.id)
|
|
|
|
.group("posts.user_id")
|
|
|
|
.order("COUNT(*) DESC")
|
|
|
|
.limit(MAX_SUMMARY_RESULTS)
|
|
|
|
.pluck("posts.user_id, COUNT(*)")
|
|
|
|
.map { |user_id, count| { user_id => count } }
|
|
|
|
.reduce({}, :merge)
|
|
|
|
|
|
|
|
#TODO include chat?
|
|
|
|
|
|
|
|
fbffs = [
|
|
|
|
apply_score(most_liked_users, LIKE_SCORE),
|
|
|
|
apply_score(most_liked_by_users, LIKE_SCORE),
|
|
|
|
apply_score(users_who_most_replied_me, REPLY_SCORE),
|
|
|
|
apply_score(users_i_most_replied, REPLY_SCORE),
|
|
|
|
]
|
|
|
|
|
2025-01-09 17:55:58 +01:00
|
|
|
fbff_id =
|
2024-12-13 10:48:20 -03:00
|
|
|
fbffs
|
|
|
|
.flatten
|
|
|
|
.inject { |h1, h2| h1.merge(h2) { |_, v1, v2| v1 + v2 } }
|
2025-01-13 17:00:32 +01:00
|
|
|
&.sort_by { |_, v| -v }
|
|
|
|
&.first
|
|
|
|
&.first
|
|
|
|
|
|
|
|
return if !fbff_id
|
2024-12-13 10:48:20 -03:00
|
|
|
|
2025-01-09 17:55:58 +01:00
|
|
|
{
|
|
|
|
data: {
|
|
|
|
fbff: BasicUserSerializer.new(User.find(fbff_id), root: false).as_json,
|
|
|
|
yourself: BasicUserSerializer.new(user, root: false).as_json,
|
|
|
|
},
|
|
|
|
identifier: "fbff",
|
|
|
|
}
|
2024-12-13 10:48:20 -03:00
|
|
|
end
|
|
|
|
|
|
|
|
def post_query(user, date)
|
|
|
|
Post
|
|
|
|
.joins(:topic)
|
|
|
|
.includes(:topic)
|
|
|
|
.where(
|
|
|
|
"posts.post_type IN (?)",
|
2024-12-13 16:57:40 +01:00
|
|
|
Topic.visible_post_types(user, include_moderator_actions: false),
|
2024-12-13 10:48:20 -03:00
|
|
|
)
|
|
|
|
.joins(
|
|
|
|
"INNER JOIN posts replies ON posts.topic_id = replies.topic_id AND posts.reply_to_post_number = replies.post_number",
|
|
|
|
)
|
|
|
|
.joins(
|
|
|
|
"INNER JOIN topics ON replies.topic_id = topics.id AND topics.archetype <> 'private_message'",
|
|
|
|
)
|
|
|
|
.joins(
|
|
|
|
"AND replies.post_type IN (#{Topic.visible_post_types(user, include_moderator_actions: false).join(",")})",
|
|
|
|
)
|
|
|
|
.where("replies.created_at BETWEEN ? AND ?", date.first, date.last)
|
|
|
|
.where("replies.user_id <> posts.user_id")
|
|
|
|
end
|
|
|
|
|
|
|
|
def like_query(date)
|
|
|
|
UserAction
|
|
|
|
.joins(:target_topic, :target_post)
|
|
|
|
.where(created_at: date)
|
|
|
|
.where(action_type: UserAction::WAS_LIKED)
|
|
|
|
end
|
|
|
|
|
|
|
|
def apply_score(users, score)
|
|
|
|
users.map { |user_id, count| { user_id => count * score } }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|