canvas-lms/app/models/notification_policy.rb

156 lines
5.8 KiB
Ruby

#
# Copyright (C) 2011 Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
class NotificationPolicy < ActiveRecord::Base
belongs_to :notification
belongs_to :user
belongs_to :communication_channel
before_save :infer_frequency
attr_accessible :notification, :user, :communication_channel, :frequency, :notification_id, :user_id, :communication_channel_id
# This is for choosing a policy for another context, so:
# user.notification_policies.for(notification) or
# user.notification_policies.for(communication_channel) or
# communication_channel.notification_policies.for(notification)
named_scope :for, lambda { |context|
case context
when User
{ :conditions => ['notification_policies.user_id = ?', context.id] }
when Notification
{ :conditions => ['notification_policies.notification_id = ?', context.id] }
when CommunicationChannel
{ :conditions => ['notification_policies.communication_channel_id = ?', context.id] }
else
{}
end
}
# TODO: the named_scope name should be self-explanatory... change
# this to by_frequency or something
# This is for choosing a policy by frequency
named_scope :by, lambda { |freq|
case freq
when Array
{ :conditions => { :frequency => freq.map{|f| f.to_s} } }
else
{ :conditions => ['notification_policies.frequency = ?', freq.to_s] }
end
}
named_scope :where, lambda { |where| { :include => [:communication_channel], :conditions => where } }
named_scope :in_state, lambda { |state| { :conditions => ["notification_policies.workflow_state = ?", state.to_s] } }
named_scope :for_channel, lambda { |channel| { :conditions => ['notification_policies.communication_channel_id = ?', channel.id] } }
def infer_frequency
self.frequency ||= "immediately"
end
protected :infer_frequency
def communication_preference
return nil unless broadcast
communication_channel || user.communication_channel
end
def self.spam_blocked_by(user)
NotificationPolicy.delete_all({:user_id => user.id})
cc = user.communication_channel
cc.confirm
Notification.all.each do |notification|
if notification.category == "Message"
NotificationPolicy.create(:notification => notification, :user => user, :communication_channel => cc, :frequency => 'immediately')
else
NotificationPolicy.create(:notification => notification, :user => user, :communication_channel => cc, :frequency => 'never')
end
end
true
rescue => e
puts e.to_s
false
end
def self.refresh_for(user)
categories = Notification.dashboard_categories
policies = user.notification_policies.to_a
params = {}
categories.each do |category|
ps = policies.select{|p| p.notification_id == category.id }
params["category_#{category.category_slug}".to_sym] = {}
ps.each do |p|
params["category_#{category.category_slug}".to_sym]["channel_#{p.communication_channel_id}"] = p.frequency
end
end
setup_for(user, params)
end
def self.setup_for(user, params)
@user = user
user.preferences[:send_scores_in_emails] = params[:root_account] &&
params[:root_account].settings[:allow_sending_scores_in_emails] != false &&
params[:user] && params[:user][:send_scores_in_emails] == '1'
params[:user].delete :send_scores_in_emails
@user.update_attributes(params[:user])
@old_policies = @user.notification_policies
@channels = @user.communication_channels
categories = Notification.dashboard_categories
prefs_to_save = []
categories.each do |category|
category_data = params["category_#{category.category_slug}".to_sym]
channels = []
if category_data
category_data.each do |key, value|
tag, id = key.split("_", 2)
channels << @channels.find(id) if tag == "channel" rescue nil
end
channels.compact!
notifications = Notification.find_all_by_category(category.category)
notifications.each do |notification|
if channels.empty?
channels << @user.communication_channel
end
if category.category == 'Message'
found_immediately = channels.any?{|c| category_data["channel_#{c.id}".to_sym] == 'immediately' }
unless found_immediately
channels << @user.communication_channel
category_data["channel_#{@user.communication_channel.id}".to_sym] = 'immediately'
end
end
channels.uniq.each do |channel|
frequency = category_data["channel_#{channel.id}".to_sym] || 'never'
pref = @user.notification_policies.new
pref.notification_id = notification.id
pref.frequency = frequency
pref.communication_channel_id = channel.id
prefs_to_save << pref
end
end
end
end
NotificationPolicy.transaction do
NotificationPolicy.connection.execute("DELETE FROM notification_policies WHERE id IN (#{@old_policies.map(&:id).join(',')})") unless @old_policies.empty?
prefs_to_save.each{|p| p.save! }
end
categories = Notification.dashboard_categories
@user.reload
@policies = @user.notification_policies.select{|p| categories.include?(p.notification)}
@policies
end
end