socialforge/app/models/mailer.rb

1083 lines
47 KiB
Ruby
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Redmine - project management software
# Copyright (C) 2006-2013 Jean-Philippe Lang
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
class Mailer < ActionMailer::Base
layout 'mailer'
helper :application
helper :issues
helper :custom_fields
include Redmine::I18n
include CoursesHelper
def self.default_url_options
{ :host => Setting.host_name, :protocol => Setting.protocol }
end
class MailerProxy
def initialize(cls)
@target = cls
end
def method_missing(name, *args, &block)
if Setting.delayjob_enabled? && Object.const_defined?('Delayed')
# with delayed_job
@target.delay.send(name, *args, &block)
else
# without delayed_job
@target.send(name, *args, &block).deliver
end
end
end
def self.run
MailerProxy.new(self)
end
# 作业匿评开启
def send_mail_anonymous_comment_open(homework_common)
course = homework_common.course
recipients ||= []
course.members.each do |member|
user = User.find(member.user_id)
@subject = "#{l(:mail_homework)}#{homework_common.name} #{l(:mail_anonymous_comment_open)}"
@token = Token.get_token_from_user(user, 'autologin')
@anonymous_comment_close_url = url_for(student_work_index_url(:homework => homework_common.id, :token => @token.value))
@anonymous_comment_close_name = homework_common.name
@author = homework_common.user
#收件人邮箱
recipients << user.mail
end
mail :to => recipients,
:subject => @subject
end
# 作业匿评关闭
def send_mail_anonymous_comment_close(homework_common)
course = homework_common.course
recipients ||= []
course.members.each do |member|
user = User.find(member.user_id)
@subject = "#{l(:mail_homework)}#{homework_common.name} #{l(:mail_anonymous_comment_close)}"
@token = Token.get_token_from_user(user, 'autologin')
@anonymous_comment_close_url = url_for(student_work_index_url(:homework => homework_common.id, :token => @token.value))
@anonymous_comment_close_name = homework_common.name
@author = homework_common.user
#收件人邮箱
recipients << user.mail
end
mail :to => recipients,
:subject => @subject
end
# 匿评失败给老师发送邮件通知
def send_mail_anonymous_comment_fail(homework_common)
course = homework_common.course
recipients ||= []
# 只给该课程的老师发送邮件提醒
course.members.each do |member|
if member.user.allowed_to?(:as_teacher,course)
user = User.find(member.user_id)
@subject = "[#{l(:mail_homework)} #{homework_common.name}] #{l(:mail_anonymous_comment_failed)}"
@token = Token.get_token_from_user(user, 'autologin')
@anonymous_comment_fail_url = url_for(student_work_index_url(:homework => homework_common.id, :token => @token.value))
@anonymous_comment_fail_name = homework_common.name
@author = homework_common.user
#收件人邮箱
recipients << user.mail
end
end
mail :to => recipients,
:subject => @subject
end
# author: alan
# 邀请未注册用户加入项目
# 功能: 在加入项目的同时自动注册用户
def send_invite_in_project(email, project, invitor, first_name, last_name, gender)
@email = email
@subject = "#{invitor.name} #{l(:label_invite_project)} #{project.name} "
@password = newpass(6)
login = email
login = login.sub(/%40/,'@')
us = UsersService.new
# 自动激活用户
user = us.register_auto(login, email, @password, first_name, last_name, gender)
InviteList.create(:user_id => user.id, :project_id => project.id, :mail =>email)
User.current = user unless User.current.nil?
@user = user
@token = Token.get_token_from_user(user, 'autologin')
@project_url = url_for(:controller => 'projects', :action => 'member', :id => project.id, :mail => true, :token => @token.value)
mail :to => email, :subject => @subject
end
# 邀请已注册的用户加入项目
def request_member_to_project(email, project, invitor)
@subject = "#{invitor.name} #{l(:label_invite_project)}: #{project.name} "
user = User.find_by_mail(email.to_s)
@invitor_name = "#{invitor.name}"
@project_name = "#{project.name}"
@user = user
@project = project
if InviteList.where("project_id= ? and user_id =? and mail =?", project.id, @user.id, email).first.nil?
InviteList.create(:user_id => user.id, :project_id => project.id, :mail => email)
end
@token = Token.get_token_from_user(user, 'autologin')
@project_url = url_for(:controller => 'projects', :action => 'member', :id => project.id, :user_id => user.id, :mail => true, :token => @token.value)
# 发送消息邀请
send_message_request_member(user,project)
# end
mail :to => email, :subject => @subject
end
# 邀请信息消息 注forge_message_id 为邀请人ID(特殊情况)
def send_message_request_member(user, project)
key = newpass(6).to_s
ForgeMessage.create(:user_id => user.id, :project_id => project.id, :forge_message_type => "ProjectInvite",:forge_message_id => User.current.id, :viewed => false, :secret_key =>key)
end
# author: alan
# 根据用户选择发送个人日报或周报
# 发送内容: 项目【缺陷,讨论区,新闻】,课程【通知,留言,新闻】, 贴吧, 个人留言
def send_for_user_activities(user, date_to, days)
date_from = date_to - days.days
date_from = "#{date_from} 17:59:59"
date_to = "#{date_to} 17:59:59"
# 生成token用于直接点击登录
@user = user
@token = Token.get_token_from_user(user, 'autologin')
# 查询user参加的项目及课程
projects = user.projects
courses = user.courses
project_ids = projects.map{|project| project.id}.join(",")
course_ids = courses.map {|course| course.id}.join(",")
# 查询user的缺陷项目中成员都能收到
sql = "select DISTINCT * from members m, issues i where i.project_id = m.project_id and m.user_id='#{user.id}'
and (i.updated_on between '#{date_from}' and '#{date_to}') order by i.project_id, i.updated_on desc"
@issues = Issue.find_by_sql(sql)
# issue回复
@issues_journals = Journal.find_by_sql("select j.* from journals j, members m, projects p, issues i
where m.user_id = '#{user.id}' and p.id = m.project_id and i.project_id = p.id and j.journalized_id = i.id
and j.journalized_type='Issue' and (j.created_on between '#{date_from}' and '#{date_to}') order by i.project_id, created_on desc")
# @bids 查询课程作业包括老师发布的作业以及user提交作业
# @attachments查询课程课件更新
@attachments ||= []
@bids ||= [] # 老师发布的作业
unless courses.first.nil?
count = courses.count
count = count - 1
for i in 0..count do
bids = courses[i].homework_commons.where("homework_commons.created_at between '#{date_from}' and '#{date_to}'").order("homework_commons.created_at desc")
attachments = courses[i].attachments.where("attachments.created_on between '#{date_from}' and '#{date_to}'")
@bids += bids if bids.count > 0
@attachments += attachments if attachments.count > 0
end
# @bids = @bids.sort_by { |obj| obj.created_at }
end
# 项目附件
@project_attachments = Attachment.find_by_sql("select DISTINCT a.* from members m, attachments a
where a.container_id = m.project_id and m.user_id='#{user.id}' and container_type = 'Project' and (a.created_on between '#{date_from}' and '#{date_to}') order by m.project_id, a.created_on desc")
# user 提交的作业
# @homeworks = HomeworkAttach.where("user_id=#{user.id} and (created_at between '#{date_from}' and '#{date_to}')").order("created_at desc")
# 查询user所在项目添加wiki
@wiki_contents = WikiContent.find_by_sql("select DISTINCT wc.* from wikis w, members m, projects p, wiki_pages wp, wiki_contents wc where
m.user_id = '#{user.id}' and m.project_id = p.id and w.project_id = p.id and w.id = wp.wiki_id and wc.page_id = wp.id and w.project_id>0
and (wc.updated_on between '#{date_from}' and '#{date_to}') order by m.project_id, updated_on desc")
# 查询user在课程中发布的讨论帖子
course_mesages = Message.find_by_sql("select DISTINCT me.* from messages me, boards b, members m where
b.id = me.board_id and b.course_id = m.course_id
and b.course_id is not Null and m.user_id = '#{user.id}'
and (me.created_on between '#{date_from}' and '#{date_to}') order by m.course_id, created_on desc")
# 查询user在项目中发布的讨论帖子
project_messages = Message.find_by_sql("select DISTINCT me.* from messages me, boards b, members m where
b.id = me.board_id and b.project_id = m.project_id
and b.project_id != '-1' and m.user_id = '#{user.id}' and (me.created_on between '#{date_from}' and '#{date_to}') order by m.project_id, created_on desc")
# messages = Message.find_by_sql("select DISTINCT * from messages where author_id = #{user.id} and (created_on between '#{date_from}' and '#{date_to}') order by created_on desc")
@course_messages ||= []
@project_messages ||= []
unless course_mesages.first.nil?
course_mesages.each do |msg|
@course_messages << msg
end
end
unless project_messages.first.nil?
project_messages.each do |msg|
@project_messages << msg
end
end
# wiki
# 查询user在课程中发布的通知和回复通知
@course_news = (course_ids && !course_ids.empty?) ? News.find_by_sql("select DISTINCT n.* from news n
where n.course_id in (#{course_ids})
and (created_on between '#{date_from}' and '#{date_to}') order by n.course_id, created_on desc") : []
@course_news_comments = Comment.find_by_sql("select cm.* from comments cm, members m, courses c, news n
where m.user_id = '#{user.id}' and c.id = m.course_id and n.course_id = c.id and cm.commented_id = n.id
and cm.commented_type ='News' and (cm.created_on between '#{date_from}' and '#{date_to}') order by m.course_id, created_on desc")
# 查询user在项目中添加新闻和回复新闻
@project_news = (project_ids && !project_ids.empty?) ? News.find_by_sql("select DISTINCT n.* from news n where n.project_id in (#{project_ids})
and (created_on between '#{date_from}' and '#{date_to}') order by n.project_id, created_on desc") : []
@project_news_comments = Comment.find_by_sql("select c.* from comments c, members m, projects p, news n
where m.user_id = '#{user.id}' and p.id = m.project_id and n.project_id = p.id and c.commented_id = n.id
and c.commented_type ='News' and (c.created_on between '#{date_from}' and '#{date_to}') order by m.project_id, created_on desc")
# 查询user在课程及个人中留言
@course_journal_messages = JournalsForMessage.find_by_sql("select DISTINCT jfm.* from journals_for_messages jfm, members m, courses c
where m.user_id = '#{user.id}' and c.id = m.course_id and jfm.jour_id = c.id
and jfm.jour_type='Course' and (jfm.created_on between '#{date_from}' and '#{date_to}') order by m.course_id, created_on desc")
@user_journal_messages = user.journals_for_messages.where("jour_type='Principal' and (created_on between '#{date_from}' and '#{date_to}')").order('created_on DESC')
# 查询user在项目中留言用户反馈
@project_journal_messages = JournalsForMessage.find_by_sql("select DISTINCT jfm.* from journals_for_messages jfm, members m, projects p
where m.user_id = '#{user.id}' and p.id = m.project_id and jfm.jour_id = p.id
and jfm.jour_type='Project' and (jfm.created_on between '#{date_from}' and '#{date_to}') order by m.project_id, created_on desc")
# 查询user新建贴吧或发布帖子
@forums = Forum.find_by_sql("select DISTINCT * from forums where creator_id = #{user.id} and (created_at between '#{date_from}' and '#{date_to}') order by created_at desc")
@memos = Memo.find_by_sql("select DISTINCT m.* from memos m, forums f where (m.author_id = #{user.id} or (m.forum_id = f.id and f.creator_id = #{user.id}))
and (m.created_at between '#{date_from}' and '#{date_to}') order by m.created_at desc")
has_content = [@issues,@issues_journals,@course_messages,@project_messages,@course_news,@course_news_comments,@project_news,@project_news_comments,@project_attachments,
@course_journal_messages,@user_journal_messages,@project_journal_messages,@forums,@memos,@attachments,@bids,@wiki_contents].any? {|o| !o.empty?}
total_count = @issues.count + @issues_journals.count + @course_messages.count + @project_messages.count + @course_news.count + @course_news_comments.count + @project_news.count + @project_news_comments.count +
@project_attachments.count + @course_journal_messages.count + @user_journal_messages.count + @project_journal_messages.count + @forums.count + @memos.count + @attachments.count +
@bids.count + @wiki_contents.count
subject = "[ #{user.show_name}#{l(:label_day_mail_first)}#{total_count}#{l(:label_day_mail_last)}]"
@subject = " #{user.show_name}#{l(:label_day_mail_first)}#{total_count}#{l(:label_day_mail_last)}"
mylogger.debug "Sent activity mail : #{user.mail} - #{has_content}"
#有内容才发,没有不发
mail :to => user.mail,:subject => @subject if has_content
end
# 作业截止时间邮件提醒
def homework_endtime__added(homework_common, user_id)
user = User.find(user_id)
@subject = "#{l(:mail_homework)}#{homework_common.name} #{l(:mail_homework_endtime)} "
@token = Token.get_token_from_user(user, 'autologin')
@homework_endtime_url = url_for(student_work_index_url(:homework => homework_common.id, :token => @token.value))
@homework_endtime_name = homework_common.name
@author = homework_common.user
#收件人邮箱
recipient = user.mail
mail :to => recipient,
:subject => @subject
end
# 公共讨论区发帖、回帖添加邮件发送信息
def forum_message_added(memo)
@memo = memo
redmine_headers 'Memo' => memo.id
@forum = memo.forum
@author = memo.author
@forum_url = url_for(:controller => 'forums', :action => 'show', :id => @forum.id)
@issue_author_url = url_for(user_activities_url(@author))
recipients ||= []
#将帖子创建者邮箱地址加入数组
recipients << @forum.creator.mail
#回复人邮箱地址加入数组
recipients << @author.mail
# cc = wiki_content.page.wiki.watcher_recipients - recipients
@memo_url = url_for(forum_memo_url(@forum, (@memo.parent_id.nil? ? @memo : @memo.parent_id)))
mail :to => recipients,
:subject => "[ #{l(:label_message_plural)} : #{memo.subject} #{l(:label_memo_create_succ)}]",
:filter => true
end
# Builds a Mail::Message object used to email recipients of the added journals for message.
# 留言分为直接留言,和对留言人留言的回复
# 字段说明在JournalsForMessage.rb
# 直接留言后 reply_id,m_parent_id 为空相对应的at_user取值为nil
def journals_for_message_add(user, journals_for_message)
@user = journals_for_message.user # 留言人
@mail = journals_for_message.jour if journals_for_message.at_user.nil? # 留言
@mail = journals_for_message.at_user if journals_for_message.at_user
@message = journals_for_message.notes
@title = "#@user #{t(:label_leave_your_message, :locale => 'zh')}"
@issue_author_url = url_for(user_activities_url(@user))
@url = case journals_for_message.jour.class.to_s.to_sym # 判断留言的对象所属类型
# when :Bid
# course_for_bid_url(journals_for_message.jour, anchor: "word_li_#{journals_for_message.id}")
when :Project
return -1 if journals_for_message.jour.project_type == Project::ProjectType_project
project_feedback_url(journals_for_message.jour, anchor: "word_li_#{journals_for_message.id}")
when :Course
course_feedback_url(journals_for_message.jour, anchor: "word_li_#{journals_for_message.id}")
when :Contest
show_contest_contest_url(journals_for_message.jour, anchor: "word_li_#{journals_for_message.id}")
when :User
user_newfeedback_user_url(journals_for_message.jour, anchor: "word_li_#{journals_for_message.id}")
else
Rails.logger.error "[Builds a Mail::Message ERROR] journalsForMessage's jour is unkown type, journalsForMessage.id = #{journals_for_message.id}"
return -1
end
# 验证用户的收取邮件的方式
recipients ||= []
recipients1 ||= []
recipients1 = @mail.mail
recipients = journals_for_message.jour.author.mail
# modify by nwb
#如果是直接留言并且留言对象是课程
if !journals_for_message.at_user && journals_for_message.jour.class.to_s.to_sym == :Course
course = journals_for_message.jour
@author = journals_for_message.user
#课程的教师
@members = course_all_member journals_for_message.jour
#收件人邮箱
@recipients ||= []
@members.each do |teacher|
@recipients << teacher.user.mail
end
mail :to => @recipients,
:subject => "#{l(:label_your_course)}#{journals_for_message.jour.name}#{l(:label_have_message)} ",
:filter => true
# elsif journals_for_message.jour.class.to_s.to_sym == :Bid
# if !journals_for_message.jour.author.notify_about? journals_for_message
# return -1
# end
#
# mail :to => recipients, :subject => @title,:filter => true
elsif journals_for_message.jour.class.to_s.to_sym == :Contest
if !journals_for_message.jour.author.notify_about? journals_for_message
return -1
end
mail :to => recipients, :subject => @title,:filter => true
else
mail :to => recipients1, :subject => @title,:filter => true
end
end
# Builds a Mail::Message object used to email recipients of the added issue.
#
# Example:
# issue_add(issue) => Mail::Message object
# Mailer.issue_add(issue).deliver => sends an email to issue recipients
def issue_add(issue, recipients)
issue_id = issue.project_index
redmine_headers 'Project' => issue.project.identifier,
'Issue-Id' => issue_id,
'Issue-Author' => issue.author.login
redmine_headers 'Issue-Assignee' => issue.assigned_to.login if issue.assigned_to
message_id issue
@author = issue.author
@issue = issue
user = User.find_by_mail(recipients)
@user = user
# @token = Token.get_token_from_user(user, 'autologin')
@issue_url = url_for(:controller => 'issues', :action => 'show', :id => issue.id)
# edit
@issue_author_url = url_for(user_activities_url(@author))
@project_url = url_for(:controller => 'projects', :action => 'show', :id => issue.project_id)
@user_url = url_for(my_account_url(user))
subject = "[#{issue.project.name} - #{issue.tracker.name} ##{issue_id}] (#{issue.status.name}) #{issue.subject}"
mail :to => recipients,
:subject => subject,
:filter => true
end
# issue.attachments.each do |attach|
# attachments["#{attach.filename}"] = File.read("#{attach.disk_filename}")
# end
# cc = issue.watcher_recipients - recipients
#mail.attachments['test'] = File.read("#{RAILS.root}/files/2015/01/150114094010_libegl.dll")
# Builds a Mail::Message object used to email recipients of the edited issue.
#
# Example:
# issue_edit(journal) => Mail::Message object
# Mailer.issue_edit(journal).deliver => sends an email to issue recipients
def issue_edit(journal,recipients)
issue = journal.journalized.reload
issue_id = issue.project_index
redmine_headers 'Project' => issue.project.identifier,
'Issue-Id' => issue_id.to_s,
'Issue-Author' => issue.author.login
redmine_headers 'Issue-Assignee' => issue.assigned_to.login if issue.assigned_to
message_id journal
references issue
@author = journal.user
user = User.find_by_mail(recipients)
@user = user
# @token = Token.get_token_from_user(user, 'autologin')
# edit
@issue_author_url = url_for(:controller => 'users', :action => 'show', :id => issue.author_id)
@project_url = url_for(:controller => 'projects', :action => 'show', :id => issue.project_id)
@user_url = url_for(my_account_url(user))
@issue_url = url_for(:controller => 'issues', :action => 'show', :id => issue.id, :anchor => "change-#{journal.id}")
s = "[#{issue.project.name} - #{issue.tracker.name} ##{issue_id}] "
s << "(#{issue.status.name}) " if journal.new_value_for('status_id')
s << issue.subject
@issue = issue
@journal = journal
# @issue_url = url_for(:controller => 'issues', :action => 'show', :id => issue, :anchor => "change-#{journal.id}")
mail :to => recipients,
:subject => s,
:filter => true
end
def self.deliver_mailer(to,cc, subject)
mail :to => to,
:cc => cc,
:subject => subject
end
# 用户申请加入项目邮件通知
def applied_project(applied)
@project =applied.project
redmine_headers 'Project' => @project,
'User' => applied.user
@user = applied.user
recipients = @project.manager_recipients
s = l(:text_applied_project, :id => "##{@user.show_name}", :project => @project.name)
@token = Token.get_token_from_user(@user, 'autologin')
@applied_url = url_for(:controller => 'projects', :action => 'settings', :id => @project.id,:tab=>'members')
mail :to => recipients,
:subject => s
end
def reminder(user, issues, days)
set_language_if_valid user.language
@issues = issues
@days = days
@issues_url = url_for(:controller => 'issues', :action => 'index',
:set_filter => 1, :assigned_to_id => user.id,
:sort => 'due_date:asc')
mail :to => user.mail,
:subject => l(:mail_subject_reminder, :count => issues.size, :days => days)
end
#缺陷到期邮件通知
def issue_expire issue
issue_id = issue.project_index
redmine_headers 'Project' => issue.project.identifier,
'Issue-Id' => issue_id,
'Issue-Author' => issue.author.login
redmine_headers 'Issue-Assignee' => issue.assigned_to.login if issue.assigned_to
message_id issue
@author = issue.author
@issue = issue
@issue_url = url_for(:controller => 'issues', :action => 'show', :id => issue.id)
recipients = issue.recipients
s = l(:text_issue_expire,:issue => "[#{issue.project.name} - #{issue.tracker.name} ##{issue_id}] (#{issue.status.name}) #{issue.subject}")
mail :to => recipients,
:subject => s
#########################################################################################################
#@issues = issues
#s = l(:text_issue_expire,:issue => "[#{issue.project.name} - #{issue.tracker.name} ##{issue_id}] (#{issue.status.name}) #{issue.subject}")
#puts s + "////" + issue.assigned_to.mail
#@issues_url = url_for(:controller => 'issues', :action => 'show',:id => issue.id)
#mail :to => issue.assigned_to.mail,
# :subject => s
#########################################################################################################
#issue_id = issue.project_index
#redmine_headers 'Project' => issue.project.identifier,
# 'Issue-Id' => issue_id,
# 'Issue-Author' => issue.author.login
#redmine_headers 'Issue-Assignee' => issue.assigned_to.login if issue.assigned_to
#message_id issue
#@author = issue.author
#@issue = issue
#@issue_url = url_for(:controller => 'issues', :action => 'show', :id => issue)
#recipients = issue.recipients
#cc = issue.watcher_recipients - recipients
#mail :to => recipients,
# :cc => cc,
# :subject => "[#{issue.project.name} - #{issue.tracker.name} ##{issue_id}] (#{issue.status.name}) #{issue.subject}"
######################################################################################################
end
# Builds a Mail::Message object used to email users belonging to the added document's project.
#
# Example:
# document_added(document) => Mail::Message object
# Mailer.document_added(document).deliver => sends an email to the document's project recipients
def document_added(document)
redmine_headers 'Project' => document.project.identifier
@author = User.current
@document = document
@issue_author_url = url_for(user_activities_url(@author))
@document_url = url_for(:controller => 'documents', :action => 'show', :id => document)
mail :to => document.recipients,
:subject => "[#{document.project.name}] #{l(:label_document_new)}: #{document.title}",
:filter => true
end
# Builds a Mail::Message object used to email recipients of a project when an attachements are added.
#
# Example:
# attachments_added(attachments) => Mail::Message object
# Mailer.attachments_added(attachments).deliver => sends an email to the project's recipients
def attachments_added(attachments)
container = attachments.first.container
added_to = ''
added_to_url = ''
@author = attachments.first.author
@issue_author_url = url_for(user_activities_url(@author))
case container.class.name
when 'Project'
added_to_url = url_for(:controller => 'files', :action => 'index', :project_id => container)
added_to = "#{l(:label_project)}: #{container}"
recipients = container.notified_users.select { |user| user.allowed_to?(:view_files, container) }.collect { |u| u.mail }
when 'Course'
added_to_url = url_for(:controller => 'files', :action => 'index', :course_id => container)
added_to = "#{l(:label_course)}: #{container.name}"
recipients = container.notified_users.select { |user| user.allowed_to?(:view_files, container) }.collect { |u| u.mail }
when 'Version'
added_to_url = url_for(:controller => 'files', :action => 'index', :project_id => container.project)
added_to = "#{l(:label_version)}: #{container.name}"
recipients = container.project.notified_users.select { |user| user.allowed_to?(:view_files, container.project) }.collect { |u| u.mail }
when 'Document'
added_to_url = url_for(:controller => 'documents', :action => 'show', :id => container.id)
added_to = "#{l(:label_document)}: #{container.title}"
recipients = container.recipients
end
if container.class.name == 'Course'
redmine_headers 'Course' => container.id
@attachments = attachments
@added_to = added_to
@added_to_url = added_to_url
mail :to => recipients,
:subject => "[#{container.name}] #{l(:label_attachment_new)}",
:filter => true
elsif container.class.name == 'Project'
redmine_headers 'Project' => container.id
@attachments = attachments
@added_to = added_to
@added_to_url = added_to_url
mail :to => recipients,
:subject => "[#{container.name}] #{l(:label_attachment_new)}",
:filter => true
else
redmine_headers 'Project' => container.project.identifier
@attachments = attachments
@added_to = added_to
@added_to_url = added_to_url
mail :to => recipients,
:subject => "[#{container.project.name}] #{l(:label_attachment_new)}",
:filter => true
end
end
# Builds a Mail::Message object used to email recipients of a course when an homework are posted.
#
# Example:
# attachments_added(attachments) => Mail::Message object
# Mailer.attachments_added(attachments).deliver => sends an email to the project's recipients
def homework_added(homework_common)
@homework_common = homework_common
@author = homework_common.user
@homework_common_url = url_for(:controller => "homework_common", :action =>"index", :homework => @homework_common.id)
@homework_author_url = url_for(user_activities_url(@author))
recipients ||= []
#将帖子创建者邮箱地址加入数组
@homework_common.course.members.each do |member|
recipients << member.user.mail
end
mail :to => recipients,
:subject => "[ #{l(:label_user_homework)} : #{homework_common.name} #{l(:label_memo_create_succ)}]",
:filter => true
end
# Builds a Mail::Message object used to email recipients of a news' project when a news item is added.
#
# Example:
# news_added(news) => Mail::Message object
# Mailer.news_added(news).deliver => sends an email to the news' project recipients
def news_added(news)
if news.project
redmine_headers 'Project' => news.project.identifier
@author = news.author
@issue_author_url = url_for(user_activities_url(@author))
message_id news
@news = news
@news_url = url_for(:controller => 'news', :action => 'show', :id => news)
mail :to => news.recipients,
:subject => "[#{news.project.name}] #{l(:label_news)}: #{news.title}",
:filter => true
elsif news.course
redmine_headers 'Course' => news.course.id
@author = news.author
@issue_author_url = url_for(user_activities_url(@author))
message_id news
@news = news
recipients = news.course.notified_users.select { |user| user.allowed_to?(:view_files, news.course) }.collect { |u| u.mail }
@news_url = url_for(:controller => 'news', :action => 'show', :id => news)
mail :to => recipients,
:subject => "[#{news.course.name}] #{l(:label_news)}: #{news.title}",
:filter => true
end
end
# Builds a Mail::Message object used to email recipients of a news' project when a news comment is added.
#
# Example:
# news_comment_added(comment) => Mail::Message object
# Mailer.news_comment_added(comment) => sends an email to the news' project recipients
def news_comment_added(comment)
news = comment.commented
if news.project
redmine_headers 'Project' => news.project.identifier
@author = comment.author
@issue_author_url = url_for(user_activities_url(@author))
message_id comment
@news = news
@comment = comment
@news_url = url_for(:controller => 'news', :action => 'show', :id => news)
mail :to => news.recipients,
:cc => news.watcher_recipients,
:subject => "Re: [#{news.project.name}] #{l(:label_news)}: #{news.title}",
:filter => true
elsif news.course
redmine_headers 'Course' => news.course.id
@author = comment.author
@issue_author_url = url_for(user_activities_url(@author))
message_id comment
@news = news
@comment = comment
@news_url = url_for(:controller => 'news', :action => 'show', :id => news)
recipients = news.course.notified_users.select { |user| user.allowed_to?(:view_files, news.course) }.collect { |u| u.mail }
mail :to => recipients,
:subject => "[#{news.course.name}] #{l(:label_news)}: #{news.title}",
:filter => true
end
end
# Builds a Mail::Message object used to email the recipients of the specified message that was posted.
#
# Example:
# message_posted(message) => Mail::Message object
# Mailer.message_posted(message).deliver => sends an email to the recipients
def message_posted(message)
if message.project
redmine_headers 'Project' => message.project.identifier,
'Topic-Id' => (message.parent_id || message.id)
@author = message.author
@issue_author_url = url_for(user_activities_url(@author))
message_id message
references message.parent unless message.parent.nil?
recipients = message.recipients
cc = ((message.root.watcher_recipients + message.board.watcher_recipients).uniq - recipients)
@message = message
@message_url = url_for(message.event_url)
mail :to => recipients,
:cc => cc,
:subject => "[#{message.board.project.name} - #{message.board.name} - msg#{message.root.id}] #{message.subject}",
:filter => true
elsif message.course
redmine_headers 'Course' => message.course.id,
'Topic-Id' => (message.parent_id || message.id)
@author = message.author
@issue_author_url = url_for(user_activities_url(@author))
message_id message
references message.parent unless message.parent.nil?
recipients = message.course.notified_users.select { |user| user.allowed_to?(:view_files, message.course) }.collect { |u| u.mail }
cc = ((message.root.watcher_recipients + message.board.watcher_recipients).uniq - recipients)
@message = message
@message_url = url_for(message.event_url)
mail :to => recipients,
:cc => cc,
:subject => "[#{message.board.course.name} - #{message.board.name} - msg#{message.root.id}] #{message.subject}",
:filter => true
end
end
# Builds a Mail::Message object used to email the recipients of a project of the specified wiki content was added.
#
# Example:
# wiki_content_added(wiki_content) => Mail::Message object
# Mailer.wiki_content_added(wiki_content).deliver => sends an email to the project's recipients
def wiki_content_added(wiki_content)
redmine_headers 'Project' => wiki_content.project.identifier,
'Wiki-Page-Id' => wiki_content.page.id
@author = wiki_content.author
message_id wiki_content
recipients = wiki_content.recipients
cc = wiki_content.page.wiki.watcher_recipients - recipients
@wiki_content = wiki_content
@wiki_content_url = url_for(:controller => 'wiki', :action => 'show',
:project_id => wiki_content.project,
:id => wiki_content.page.title)
mail :to => recipients,
:cc => cc,
:subject => "[#{wiki_content.project.name}] #{l(:mail_subject_wiki_content_added, :id => wiki_content.page.pretty_title)}",
:filter => true
end
# Builds a Mail::Message object used to email the recipients of a project of the specified wiki content was updated.
#
# Example:
# wiki_content_updated(wiki_content) => Mail::Message object
# Mailer.wiki_content_updated(wiki_content).deliver => sends an email to the project's recipients
def wiki_content_updated(wiki_content)
redmine_headers 'Project' => wiki_content.project.identifier,
'Wiki-Page-Id' => wiki_content.page.id
@author = wiki_content.author
message_id wiki_content
recipients = wiki_content.recipients
cc = wiki_content.page.wiki.watcher_recipients + wiki_content.page.watcher_recipients - recipients
@wiki_content = wiki_content
@wiki_content_url = url_for(:controller => 'wiki', :action => 'show',
:project_id => wiki_content.project,
:id => wiki_content.page.title)
@wiki_diff_url = url_for(:controller => 'wiki', :action => 'diff',
:project_id => wiki_content.project, :id => wiki_content.page.title,
:version => wiki_content.version)
mail :to => recipients,
:cc => cc,
:subject => "[#{wiki_content.project.name}] #{l(:mail_subject_wiki_content_updated, :id => wiki_content.page.pretty_title)}",
:filter => true
end
# Builds a Mail::Message object used to email the specified user their account information.
#
# Example:
# account_information(user, password) => Mail::Message object
# Mailer.account_information(user, password).deliver => sends account information to the user
def account_information(user, password)
set_language_if_valid user.language
@user = user
@password = password
@login_url = url_for(:controller => 'account', :action => 'login')
mail :to => user.mail,
:subject => l(:mail_subject_register, Setting.app_title)
end
# Builds a Mail::Message object used to email all active administrators of an account activation request.
#
# Example:
# account_activation_request(user) => Mail::Message object
# Mailer.account_activation_request(user).deliver => sends an email to all active administrators
def account_activation_request(user)
# Send the email to all active administrators
recipients = User.active.where(:admin => true).all.collect { |u| u.mail }.compact
@user = user
@url = url_for(:controller => 'users', :action => 'index',
:status => User::STATUS_REGISTERED,
:sort_key => 'created_on', :sort_order => 'desc')
mail :to => recipients,
:subject => l(:mail_subject_account_activation_request, Setting.app_title)
end
# Builds a Mail::Message object used to email the specified user that their account was activated by an administrator.
#
# Example:
# account_activated(user) => Mail::Message object
# Mailer.account_activated(user).deliver => sends an email to the registered user
def account_activated(user)
set_language_if_valid user.language
@user = user
@login_url = url_for(:controller => 'account', :action => 'login')
mail :to => user.mail,
:subject => l(:mail_subject_register, Setting.app_title)
end
def lost_password(token)
set_language_if_valid(token.user.language)
@token = token
@url = url_for(:controller => 'account', :action => 'lost_password', :token => token.value)
mail :to => token.user.mail,
:subject => l(:mail_subject_lost_password, Setting.app_title)
end
def register(token)
set_language_if_valid(token.user.language)
@token = token
@url = url_for(:controller => 'account', :action => 'activate', :token => token.value)
mail :to => token.user.mail,
:subject => l(:mail_subject_register, Setting.app_title)
end
def test_email(user)
set_language_if_valid(user.language)
@url = url_for(:controller => 'welcome')
mail :to => user.mail,
:subject => 'forge test'
end
# Overrides default deliver! method to prevent from sending an email
# with no recipient, cc or bcc
def deliver!(mail = @mail)
set_language_if_valid @initial_language
return false if (recipients.nil? || recipients.empty?) &&
(cc.nil? || cc.empty?) &&
(bcc.nil? || bcc.empty?)
# Log errors when raise_delivery_errors is set to false, Rails does not
raise_errors = self.class.raise_delivery_errors
self.class.raise_delivery_errors = true
begin
return super(mail)
rescue Exception => e
if raise_errors
raise e
elsif mylogger
mylogger.error "The following error occured while sending email notification: \"#{e.message}\". Check your configuration in config/configuration.yml."
end
ensure
self.class.raise_delivery_errors = raise_errors
end
end
# Sends reminders to issue assignees
# Available options:
# * :days => how many days in the future to remind about (defaults to 7)
# * :tracker => id of tracker for filtering issues (defaults to all trackers)
# * :project => id or identifier of project to process (defaults to all projects)
# * :users => array of user/group ids who should be reminded
def self.reminders(options={})
days = options[:days] || 7
project = options[:project] ? Project.find(options[:project]) : nil
tracker = options[:tracker] ? Tracker.find(options[:tracker]) : nil
user_ids = options[:users]
scope = Issue.open.where("#{Issue.table_name}.assigned_to_id IS NOT NULL" +
" AND #{Project.table_name}.status = #{Project::STATUS_ACTIVE}" +
" AND #{Issue.table_name}.due_date <= ?", days.day.from_now.to_date
)
scope = scope.where(:assigned_to_id => user_ids) if user_ids.present?
scope = scope.where(:project_id => project.id) if project
scope = scope.where(:tracker_id => tracker.id) if tracker
issues_by_assignee = scope.includes(:status, :assigned_to, :project, :tracker).all.group_by(&:assigned_to)
issues_by_assignee.keys.each do |assignee|
if assignee.is_a?(Group)
assignee.users.each do |user|
issues_by_assignee[user] ||= []
issues_by_assignee[user] += issues_by_assignee[assignee]
end
end
end
issues_by_assignee.each do |assignee, issues|
reminder(assignee, issues, days).deliver if assignee.is_a?(User) && assignee.active?
end
end
# Activates/desactivates email deliveries during +block+
def self.with_deliveries(enabled = true, &block)
was_enabled = ActionMailer::Base.perform_deliveries
ActionMailer::Base.perform_deliveries = !!enabled
yield
ensure
ActionMailer::Base.perform_deliveries = was_enabled
end
# Sends emails synchronously in the given block
def self.with_synched_deliveries(&block)
saved_method = ActionMailer::Base.delivery_method
if m = saved_method.to_s.match(%r{^async_(.+)$})
synched_method = m[1]
ActionMailer::Base.delivery_method = synched_method.to_sym
ActionMailer::Base.send "#{synched_method}_settings=", ActionMailer::Base.send("async_#{synched_method}_settings")
end
yield
ensure
ActionMailer::Base.delivery_method = saved_method
end
#过滤掉不是不合规则的收件人
def filter(reps)
r_reps = []
if reps.is_a? Array
reps.each do |r|
u = User.find_by_mail(r)
if u && u.mail_notification == 'all'
r_reps << r
end
end
elsif reps.is_a? String
u = User.find_by_mail(reps)
if u && u.mail_notification == 'all'
r_reps << reps
end
end
r_reps
end
def mail(headers={})
headers.merge! 'X-Mailer' => 'Redmine',
'X-Redmine-Host' => Setting.host_name,
'X-Redmine-Site' => Setting.app_title,
'X-Auto-Response-Suppress' => 'OOF',
'Auto-Submitted' => 'auto-generated',
'From' => Setting.mail_from,
'List-Id' => "<#{Setting.mail_from.to_s.gsub('@', '.')}>"
# Removes the author from the recipients and cc
# if he doesn't want to receive notifications about what he does
if @author && @author.logged? && @author.pref[:no_self_notified]
headers[:to].delete(@author.mail) if headers[:to].is_a?(Array)
headers[:cc].delete(@author.mail) if headers[:cc].is_a?(Array)
end
if headers[:filter]
headers[:to] = filter(headers[:to])
headers[:cc] = filter(headers[:cc])
end
if @author && @author.logged?
redmine_headers 'Sender' => @author.login
end
# Blind carbon copy recipients
if Setting.bcc_recipients?
headers[:bcc] = [headers[:to], headers[:cc]].flatten.uniq.reject(&:blank?)
headers[:to] = nil
headers[:cc] = nil
end
if @message_id_object
headers[:message_id] = "<#{self.class.message_id_for(@message_id_object)}>"
end
if @references_objects
headers[:references] = @references_objects.collect {|o| "<#{self.class.message_id_for(o)}>"}.join(' ')
end
set_language_if_valid @initial_language
m = super headers do |format|
format.text
format.html unless Setting.plain_text_mail?
end
mylogger.debug "Sent a mail from #{m.from} to [#{m.to},#{m.cc}, #{m.bcc if Setting.bcc_recipients?}] subject: #{m.subject}"
m
end
def initialize(*args)
@initial_language = current_language
set_language_if_valid Setting.default_language
super
end
def self.deliver_mail(mail)
return false if mail.to.blank? && mail.cc.blank? && mail.bcc.blank?
Thread.new do
super
end
end
def self.method_missing(method, *args, &block)
if m = method.to_s.match(%r{^deliver_(.+)$})
ActiveSupport::Deprecation.warn "Mailer.deliver_#{m[1]}(*args) is deprecated. Use Mailer.#{m[1]}(*args).deliver instead."
send(m[1], *args).deliver
else
super
end
end
def join_course_request(course, user, role)
@receive = User.find(course.tea_id)
@course = course
@user = user
@role = role
@subject = "#{@user.show_name} #{l(:label_apply_join_course)} #{@course.name} "
mail :to => @receive.mail,
:subject => @subject
end
private
# Appends a Redmine header field (name is prepended with 'X-Redmine-')
def redmine_headers(h)
h.each { |k,v| headers["X-Redmine-#{k}"] = v.to_s }
end
# Returns a predictable Message-Id for the given object
def self.message_id_for(object)
# id + timestamp should reduce the odds of a collision
# as far as we don't send multiple emails for the same object
timestamp = object.send(object.respond_to?(:created_on) ? :created_on : :updated_on)
hash = "redmine.#{object.class.name.demodulize.underscore}-#{object.id}.#{timestamp.strftime("%Y%m%d%H%M%S")}"
host = Setting.mail_from.to_s.gsub(%r{^.*@}, '')
host = "#{::Socket.gethostname}.redmine" if host.empty?
"#{hash}@#{host}"
end
def message_id(object)
@message_id_object = object
end
def references(object)
@references_objects ||= []
@references_objects << object
end
def mylogger
if Setting.delayjob_enabled?
Delayed::Worker.logger
else
Rails.logger
end
end
def add_attachments(obj)
if email.attachments && email.attachments.any?
email.attachments.each do |attachment|
obj.attachments << Attachment.create(:container => obj,
:file => attachment.decoded,
:filename => attachment.filename,
:author => user,
:content_type => attachment.mime_type)
end
end
end
# author: alan
# 功能: 生成len位随机字符串
def newpass(len)
chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
newpass = ""
1.upto(len) { |i| newpass << chars[rand(chars.size-1)] }
return newpass
end
end