Skip to content

Commit

Permalink
Merge pull request #14967 from danidoni/introduce-notification-for-de…
Browse files Browse the repository at this point in the history
…cision-on-moderated-object

Introduce notifications for decisions on moderated objects
  • Loading branch information
danidoni committed Sep 28, 2023
2 parents 2eec23e + b71327f commit 9de3a31
Show file tree
Hide file tree
Showing 11 changed files with 96 additions and 7 deletions.
4 changes: 4 additions & 0 deletions src/api/app/components/notification_avatars_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ def initialize(notification)

private

# rubocop:disable Metrics/CyclomaticComplexity
def avatar_objects
@avatar_objects ||= case @notification.notifiable_type
when 'Comment'
Expand All @@ -17,11 +18,14 @@ def avatar_objects
[User.find_by(login: @notification.event_payload['who'])]
when 'Report'
[User.find(@notification.event_payload['user_id'])]
when 'Decision'
[User.find(@notification.event_payload['moderator_id'])]
else
reviews = @notification.notifiable.reviews
reviews.select(&:new?).map(&:reviewed_by) + User.where(login: @notification.notifiable.creator)
end
end
# rubocop:enable Metrics/CyclomaticComplexity

def avatars_to_display
avatar_objects.first(MAXIMUM_DISPLAYED_AVATARS).reverse
Expand Down
15 changes: 15 additions & 0 deletions src/api/app/models/decision.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,21 @@ class Decision < ApplicationRecord
cleared: 0,
favor: 1
}

after_create :create_event

def create_event
case kind
when 'cleared'
Event::ClearedDecision.create(event_parameters)
else
Event::FavoredDecision.create(event_parameters)
end
end

def event_parameters
{ id: id, moderator_id: moderator.id, reason: reason }
end
end

# == Schema Information
Expand Down
26 changes: 25 additions & 1 deletion src/api/app/models/event/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ class Base < ApplicationRecord
'Event::CommentForRequest' => 'Receive notifications of comments created on a request for which you are...',
'Event::RelationshipCreate' => "Receive notifications when someone adds you or your group to a project or package with any of these roles: #{Role.local_roles.to_sentence}.",
'Event::RelationshipDelete' => "Receive notifications when someone removes you or your group from a project or package with any of these roles: #{Role.local_roles.to_sentence}.",
'Event::CreateReport' => 'Receive notifications for reported content.'
'Event::CreateReport' => 'Receive notifications for reported content.',
'Event::ClearedDecision' => 'Receive notifications for cleared report decisions.',
'Event::FavoredDecision' => 'Receive notifications for favored report decisions.'
}.freeze

class << self
Expand Down Expand Up @@ -273,6 +275,28 @@ def moderators
User.admins.or(User.staff)
end

def reporters
decision = Decision.find(payload['id'])
decision.reports.map(&:user)
end

def offenders
decision = Decision.find(payload['id'])
reportables = decision.reports.map(&:reportable)
reportables.map do |reportable|
case reportable
when Package, Project
reportable.maintainers
when User
reportable
when BsRequest
User.find_by(login: reportable.creator)
when Comment
reportable.user
end
end
end

def _roles(role, project, package = nil)
return [] unless project

Expand Down
12 changes: 12 additions & 0 deletions src/api/app/models/event/cleared_decision.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module Event
class ClearedDecision < Base
receiver_roles :reporter
self.description = 'Reported content has been cleared'

payload_keys :id, :reason, :moderator_id

def parameters_for_notification
super.merge(notifiable_type: 'Decision')
end
end
end
12 changes: 12 additions & 0 deletions src/api/app/models/event/favored_decision.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module Event
class FavoredDecision < Base
receiver_roles :reporter, :offender
self.description = 'Reported content has been favored'

payload_keys :id, :reason, :moderator_id

def parameters_for_notification
super.merge(notifiable_type: 'Decision')
end
end
end
2 changes: 1 addition & 1 deletion src/api/app/models/event_subscription.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class EventSubscription < ApplicationRecord
in: [:maintainer, :bugowner, :reader, :source_maintainer, :target_maintainer,
:reviewer, :commenter, :creator, :watcher, :source_watcher, :target_watcher,
:package_watcher, :target_package_watcher, :source_package_watcher, :request_watcher, :any_role,
:moderator]
:moderator, :reporter, :offender]
}

scope :for_eventtype, ->(eventtype) { where(eventtype: eventtype) }
Expand Down
10 changes: 10 additions & 0 deletions src/api/app/queries/outdated_notifications_finder/decision.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class OutdatedNotificationsFinder::Decision
def initialize(scope, parameters)
@scope = scope
@parameters = parameters
end

def call
@scope.where(notifiable_type: 'Decision', notifiable_id: @parameters['notifiable_id'])
end
end
12 changes: 9 additions & 3 deletions src/api/app/services/notification_service/notifier.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,25 @@ class Notifier
'Event::CommentForRequest',
'Event::RelationshipCreate',
'Event::RelationshipDelete',
'Event::CreateReport'].freeze
'Event::CreateReport',
'Event::ClearedDecision',
'Event::FavoredDecision'].freeze
CHANNELS = [:web, :rss].freeze
ALLOWED_NOTIFIABLE_TYPES = {
'BsRequest' => ::BsRequest,
'Comment' => ::Comment,
'Project' => ::Project,
'Package' => ::Package,
'Report' => ::Report
'Report' => ::Report,
'Decision' => ::Decision
}.freeze
ALLOWED_CHANNELS = {
web: NotificationService::WebChannel,
rss: NotificationService::RSSChannel
}.freeze
REJECTED_FOR_RSS = ['Event::CreateReport',
'Event::ClearedDecision',
'Event::FavoredDecision'].freeze

def initialize(event)
@event = event
Expand All @@ -31,7 +37,7 @@ def call
return unless @event.eventtype.in?(EVENTS_TO_NOTIFY)

CHANNELS.each do |channel|
next if channel == :rss && @event.eventtype == 'Event::CreateReport'
next if channel == :rss && @event.eventtype.in?(REJECTED_FOR_RSS)

@event.subscriptions(channel).each do |subscription|
create_notification_per_subscription(subscription, channel)
Expand Down
3 changes: 2 additions & 1 deletion src/api/app/services/notification_service/web_channel.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ class WebChannel
'Comment' => OutdatedNotificationsFinder::Comment,
'Project' => OutdatedNotificationsFinder::Project,
'Package' => OutdatedNotificationsFinder::Package,
'Report' => OutdatedNotificationsFinder::Report
'Report' => OutdatedNotificationsFinder::Report,
'Decision' => OutdatedNotificationsFinder::Decision
}.freeze

def initialize(subscription, event)
Expand Down
2 changes: 1 addition & 1 deletion src/api/app/services/notified_projects.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def call
@notifiable.project
when 'Project'
@notifiable
when 'Report'
when 'Report', 'Decision'
[]
end
end
Expand Down
5 changes: 5 additions & 0 deletions src/api/lib/tasks/dev/reports.rake
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ namespace :dev do

puts 'Taking decisions regarding some reports'

# This automatically subscribes everyone to the cleared and favored decision events
EventSubscription.create!(eventtype: Event::ClearedDecision.name, channel: :web, receiver_role: :reporter, enabled: true)
EventSubscription.create!(eventtype: Event::FavoredDecision.name, channel: :web, receiver_role: :reporter, enabled: true)
EventSubscription.create!(eventtype: Event::FavoredDecision.name, channel: :web, receiver_role: :offender, enabled: true)

admin = User.get_default_admin

Report.find_each do |report|
Expand Down

0 comments on commit 9de3a31

Please sign in to comment.