diff options
author | Felipe Artur <felipefac@gmail.com> | 2016-05-31 17:51:46 -0300 |
---|---|---|
committer | Felipe Artur <felipefac@gmail.com> | 2016-06-15 11:47:50 -0300 |
commit | 89a2c8730b5d1f69703b0879d5b6b7bd5d766695 (patch) | |
tree | 456c480b86f74c4f47f334def338dbba527e9031 /app/services | |
parent | 8bfbafbb6b2166d3709187cf6b1cb7ff5f627d52 (diff) | |
download | gitlab-ce-89a2c8730b5d1f69703b0879d5b6b7bd5d766695.tar.gz |
Implement custom notification level options
Diffstat (limited to 'app/services')
-rw-r--r-- | app/services/notification_service.rb | 94 |
1 files changed, 60 insertions, 34 deletions
diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb index f804ac171c4..5bdefcc8116 100644 --- a/app/services/notification_service.rb +++ b/app/services/notification_service.rb @@ -29,9 +29,10 @@ class NotificationService # * issue assignee if their notification level is not Disabled # * project team members with notification level higher then Participating # * watchers of the issue's labels + # * users with custom level checked with "new issue" # def new_issue(issue, current_user) - new_resource_email(issue, issue.project, 'new_issue_email') + new_resource_email(issue, issue.project, :new_issue_email) end # When we close an issue we should send an email to: @@ -39,18 +40,20 @@ class NotificationService # * issue author if their notification level is not Disabled # * issue assignee if their notification level is not Disabled # * project team members with notification level higher then Participating + # * users with custom level checked with "close issue" # def close_issue(issue, current_user) - close_resource_email(issue, issue.project, current_user, 'closed_issue_email') + close_resource_email(issue, issue.project, current_user, :closed_issue_email) end # When we reassign an issue we should send an email to: # # * issue old assignee if their notification level is not Disabled # * issue new assignee if their notification level is not Disabled + # * users with custom level checked with "reassign issue" # def reassigned_issue(issue, current_user) - reassign_resource_email(issue, issue.project, current_user, 'reassigned_issue_email') + reassign_resource_email(issue, issue.project, current_user, :reassigned_issue_email) end # When we add labels to an issue we should send an email to: @@ -58,7 +61,7 @@ class NotificationService # * watchers of the issue's labels # def relabeled_issue(issue, added_labels, current_user) - relabeled_resource_email(issue, added_labels, current_user, 'relabeled_issue_email') + relabeled_resource_email(issue, added_labels, current_user, :relabeled_issue_email) end # When create a merge request we should send an email to: @@ -66,18 +69,20 @@ class NotificationService # * mr assignee if their notification level is not Disabled # * project team members with notification level higher then Participating # * watchers of the mr's labels + # * users with custom level checked with "new merge request" # def new_merge_request(merge_request, current_user) - new_resource_email(merge_request, merge_request.target_project, 'new_merge_request_email') + new_resource_email(merge_request, merge_request.target_project, :new_merge_request_email) end # When we reassign a merge_request we should send an email to: # # * merge_request old assignee if their notification level is not Disabled # * merge_request assignee if their notification level is not Disabled + # * users with custom level checked with "reassign merge request" # def reassigned_merge_request(merge_request, current_user) - reassign_resource_email(merge_request, merge_request.target_project, current_user, 'reassigned_merge_request_email') + reassign_resource_email(merge_request, merge_request.target_project, current_user, :reassigned_merge_request_email) end # When we add labels to a merge request we should send an email to: @@ -85,15 +90,15 @@ class NotificationService # * watchers of the mr's labels # def relabeled_merge_request(merge_request, added_labels, current_user) - relabeled_resource_email(merge_request, added_labels, current_user, 'relabeled_merge_request_email') + relabeled_resource_email(merge_request, added_labels, current_user, :relabeled_merge_request_email) end def close_mr(merge_request, current_user) - close_resource_email(merge_request, merge_request.target_project, current_user, 'closed_merge_request_email') + close_resource_email(merge_request, merge_request.target_project, current_user, :closed_merge_request_email) end def reopen_issue(issue, current_user) - reopen_resource_email(issue, issue.project, current_user, 'issue_status_changed_email', 'reopened') + reopen_resource_email(issue, issue.project, current_user, :issue_status_changed_email, 'reopened') end def merge_mr(merge_request, current_user) @@ -101,7 +106,7 @@ class NotificationService merge_request, merge_request.target_project, current_user, - 'merged_merge_request_email' + :merged_merge_request_email ) end @@ -110,7 +115,7 @@ class NotificationService merge_request, merge_request.target_project, current_user, - 'merge_request_status_email', + :merge_request_status_email, 'reopened' ) end @@ -153,6 +158,9 @@ class NotificationService # Merge project watchers recipients = add_project_watchers(recipients, note.project) + # Merge project with custom notification + recipients = add_project_custom_notifications(recipients, note.project, :new_note) + # Reject users with Mention notification level, except those mentioned in _this_ note. recipients = reject_mention_users(recipients - mentioned_users, note.project) recipients = recipients + mentioned_users @@ -268,12 +276,22 @@ class NotificationService protected + # Get project/group users with CUSTOM notification level + def add_project_custom_notifications(recipients, project, action) + user_ids = [] + + user_ids += notification_settings_for(project, :custom, action) + user_ids += notification_settings_for(project.group, :custom, action) + + recipients.concat(User.find(user_ids)) + end + # Get project users with WATCH notification level def project_watchers(project) - project_members = project_member_notification(project) + project_members = notification_settings_for(project) - users_with_project_level_global = project_member_notification(project, :global) - users_with_group_level_global = group_member_notification(project, :global) + users_with_project_level_global = notification_settings_for(project, :global) + users_with_group_level_global = notification_settings_for(project, :global) users = users_with_global_level_watch([users_with_project_level_global, users_with_group_level_global].flatten.uniq) users_with_project_setting = select_project_member_setting(project, users_with_project_level_global, users) @@ -282,19 +300,15 @@ class NotificationService User.where(id: users_with_project_setting.concat(users_with_group_setting).uniq).to_a end - def project_member_notification(project, notification_level=nil) - if notification_level - project.notification_settings.where(level: NotificationSetting.levels[notification_level]).pluck(:user_id) - else - project.notification_settings.pluck(:user_id) - end - end + def notification_settings_for(resource, notification_level = nil, action = nil) + return [] unless resource - def group_member_notification(project, notification_level) - if project.group - project.group.notification_settings.where(level: NotificationSetting.levels[notification_level]).pluck(:user_id) + if notification_level + settings = resource.notification_settings.where(level: NotificationSetting.levels[notification_level]) + settings = settings.select { |setting| setting.events[action] } if action.present? + settings.map(&:user_id) else - [] + resource.notification_settings.pluck(:user_id) end end @@ -308,7 +322,7 @@ class NotificationService # Build a list of users based on project notifcation settings def select_project_member_setting(project, global_setting, users_global_level_watch) - users = project_member_notification(project, :watch) + users = notification_settings_for(project, :watch) # If project setting is global, add to watch list if global setting is watch global_setting.each do |user_id| @@ -322,7 +336,7 @@ class NotificationService # Build a list of users based on group notification settings def select_group_member_setting(project, project_members, global_setting, users_global_level_watch) - uids = group_member_notification(project, :watch) + uids = notification_settings_for(project, :watch) # Group setting is watch, add to users list if user is not project member users = [] @@ -343,7 +357,7 @@ class NotificationService end def add_project_watchers(recipients, project) - recipients.concat(project_watchers(project)).compact.uniq + recipients.concat(project_watchers(project)).compact end # Remove users with disabled notifications from array @@ -428,7 +442,7 @@ class NotificationService end def new_resource_email(target, project, method) - recipients = build_recipients(target, project, target.author, action: :new) + recipients = build_recipients(target, project, target.author, action: "new") recipients.each do |recipient| mailer.send(method, recipient.id, target.id).deliver_later @@ -436,7 +450,8 @@ class NotificationService end def close_resource_email(target, project, current_user, method) - recipients = build_recipients(target, project, current_user) + action = method == :merged_merge_request_email ? "merge" : "close" + recipients = build_recipients(target, project, current_user, action: action) recipients.each do |recipient| mailer.send(method, recipient.id, target.id, current_user.id).deliver_later @@ -447,7 +462,7 @@ class NotificationService previous_assignee_id = previous_record(target, 'assignee_id') previous_assignee = User.find_by(id: previous_assignee_id) if previous_assignee_id - recipients = build_recipients(target, project, current_user, action: :reassign, previous_assignee: previous_assignee) + recipients = build_recipients(target, project, current_user, action: "reassign", previous_assignee: previous_assignee) recipients.each do |recipient| mailer.send( @@ -470,7 +485,7 @@ class NotificationService end def reopen_resource_email(target, project, current_user, method, status) - recipients = build_recipients(target, project, current_user) + recipients = build_recipients(target, project, current_user, action: "reopen") recipients.each do |recipient| mailer.send(method, recipient.id, target.id, status, current_user.id).deliver_later @@ -478,14 +493,19 @@ class NotificationService end def build_recipients(target, project, current_user, action: nil, previous_assignee: nil) + custom_action = build_custom_key(action, target) + recipients = target.participants(current_user) recipients = add_project_watchers(recipients, project) + recipients = add_project_custom_notifications(recipients, project, custom_action) recipients = reject_mention_users(recipients, project) + recipients = recipients.uniq + # Re-assign is considered as a mention of the new assignee so we add the # new assignee to the list of recipients after we rejected users with # the "on mention" notification level - if action == :reassign + if [:reassign_merge_request, :reassign_issue].include?(custom_action) recipients << previous_assignee if previous_assignee recipients << target.assignee end @@ -493,7 +513,7 @@ class NotificationService recipients = reject_muted_users(recipients, project) recipients = add_subscribed_users(recipients, target) - if action == :new + if [:new_issue, :new_merge_request].include?(custom_action) recipients = add_labels_subscribers(recipients, target) end @@ -523,4 +543,10 @@ class NotificationService end end end + + # Build event key to search on custom notification level + # Check NotificationSetting::EMAIL_EVENTS + def build_custom_key(action, object) + "#{action}_#{object.class.name.underscore}".to_sym + end end |