Revision 1298:4f746d8966dd .svn/pristine/09
| .svn/pristine/09/0950951344735156104a9fd2df5df66fc9bd2194.svn-base | ||
|---|---|---|
| 1 |
# Redmine - project management software |
|
| 2 |
# Copyright (C) 2006-2011 Jean-Philippe Lang |
|
| 3 |
# |
|
| 4 |
# This program is free software; you can redistribute it and/or |
|
| 5 |
# modify it under the terms of the GNU General Public License |
|
| 6 |
# as published by the Free Software Foundation; either version 2 |
|
| 7 |
# of the License, or (at your option) any later version. |
|
| 8 |
# |
|
| 9 |
# This program is distributed in the hope that it will be useful, |
|
| 10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 12 |
# GNU General Public License for more details. |
|
| 13 |
# |
|
| 14 |
# You should have received a copy of the GNU General Public License |
|
| 15 |
# along with this program; if not, write to the Free Software |
|
| 16 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
| 17 |
|
|
| 18 |
module Redmine |
|
| 19 |
module Views |
|
| 20 |
module Builders |
|
| 21 |
def self.for(format, &block) |
|
| 22 |
builder = case format |
|
| 23 |
when 'xml', :xml; Builders::Xml.new |
|
| 24 |
when 'json', :json; Builders::Json.new |
|
| 25 |
else; raise "No builder for format #{format}"
|
|
| 26 |
end |
|
| 27 |
if block |
|
| 28 |
block.call(builder) |
|
| 29 |
else |
|
| 30 |
builder |
|
| 31 |
end |
|
| 32 |
end |
|
| 33 |
end |
|
| 34 |
end |
|
| 35 |
end |
|
| .svn/pristine/09/095b395fcfe029ccbb2acac47d6cc8ef84b80f97.svn-base | ||
|---|---|---|
| 1 |
syntax: glob |
|
| 2 |
|
|
| 3 |
.project |
|
| 4 |
.loadpath |
|
| 5 |
config/additional_environment.rb |
|
| 6 |
config/configuration.yml |
|
| 7 |
config/database.yml |
|
| 8 |
config/email.yml |
|
| 9 |
config/initializers/session_store.rb |
|
| 10 |
coverage |
|
| 11 |
db/*.db |
|
| 12 |
db/*.sqlite3 |
|
| 13 |
db/schema.rb |
|
| 14 |
files/* |
|
| 15 |
lib/redmine/scm/adapters/mercurial/redminehelper.pyc |
|
| 16 |
lib/redmine/scm/adapters/mercurial/redminehelper.pyo |
|
| 17 |
log/*.log* |
|
| 18 |
log/mongrel_debug |
|
| 19 |
public/dispatch.* |
|
| 20 |
public/plugin_assets |
|
| 21 |
tmp/* |
|
| 22 |
tmp/cache/* |
|
| 23 |
tmp/sessions/* |
|
| 24 |
tmp/sockets/* |
|
| 25 |
tmp/test/* |
|
| 26 |
vendor/rails |
|
| 27 |
*.rbc |
|
| 28 |
|
|
| 29 |
.svn/ |
|
| 30 |
.git/ |
|
| 31 |
|
|
| 32 |
.bundle |
|
| 33 |
Gemfile.lock |
|
| 34 |
Gemfile.local |
|
| 35 |
|
|
| .svn/pristine/09/09843d45a0a3ac966e4fda0bad80ec81990f71bb.svn-base | ||
|---|---|---|
| 1 |
Net::LDAP is copyrighted free software by Francis Cianfrocca |
|
| 2 |
<garbagecat10@gmail.com>. You can redistribute it and/or modify it under either |
|
| 3 |
the terms of the GPL (see the file COPYING), or the conditions below: |
|
| 4 |
|
|
| 5 |
1. You may make and give away verbatim copies of the source form of the |
|
| 6 |
software without restriction, provided that you duplicate all of the |
|
| 7 |
original copyright notices and associated disclaimers. |
|
| 8 |
|
|
| 9 |
2. You may modify your copy of the software in any way, provided that you do |
|
| 10 |
at least ONE of the following: |
|
| 11 |
|
|
| 12 |
a) place your modifications in the Public Domain or otherwise make them |
|
| 13 |
Freely Available, such as by posting said modifications to Usenet or |
|
| 14 |
an equivalent medium, or by allowing the author to include your |
|
| 15 |
modifications in the software. |
|
| 16 |
|
|
| 17 |
b) use the modified software only within your corporation or |
|
| 18 |
organization. |
|
| 19 |
|
|
| 20 |
c) rename any non-standard executables so the names do not conflict with |
|
| 21 |
standard executables, which must also be provided. |
|
| 22 |
|
|
| 23 |
d) make other distribution arrangements with the author. |
|
| 24 |
|
|
| 25 |
3. You may distribute the software in object code or executable form, |
|
| 26 |
provided that you do at least ONE of the following: |
|
| 27 |
|
|
| 28 |
a) distribute the executables and library files of the software, together |
|
| 29 |
with instructions (in the manual page or equivalent) on where to get |
|
| 30 |
the original distribution. |
|
| 31 |
|
|
| 32 |
b) accompany the distribution with the machine-readable source of the |
|
| 33 |
software. |
|
| 34 |
|
|
| 35 |
c) give non-standard executables non-standard names, with instructions on |
|
| 36 |
where to get the original software distribution. |
|
| 37 |
|
|
| 38 |
d) make other distribution arrangements with the author. |
|
| 39 |
|
|
| 40 |
4. You may modify and include the part of the software into any other |
|
| 41 |
software (possibly commercial). But some files in the distribution are |
|
| 42 |
not written by the author, so that they are not under this terms. |
|
| 43 |
|
|
| 44 |
They are gc.c(partly), utils.c(partly), regex.[ch], st.[ch] and some |
|
| 45 |
files under the ./missing directory. See each file for the copying |
|
| 46 |
condition. |
|
| 47 |
|
|
| 48 |
5. The scripts and library files supplied as input to or produced as output |
|
| 49 |
from the software do not automatically fall under the copyright of the |
|
| 50 |
software, but belong to whomever generated them, and may be sold |
|
| 51 |
commercially, and may be aggregated with this software. |
|
| 52 |
|
|
| 53 |
6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED |
|
| 54 |
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF |
|
| 55 |
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
|
| .svn/pristine/09/09d005add00d07aeb449a6c04ad00db8e1f72fbd.svn-base | ||
|---|---|---|
| 1 |
# Redmine - project management software |
|
| 2 |
# Copyright (C) 2006-2013 Jean-Philippe Lang |
|
| 3 |
# |
|
| 4 |
# This program is free software; you can redistribute it and/or |
|
| 5 |
# modify it under the terms of the GNU General Public License |
|
| 6 |
# as published by the Free Software Foundation; either version 2 |
|
| 7 |
# of the License, or (at your option) any later version. |
|
| 8 |
# |
|
| 9 |
# This program is distributed in the hope that it will be useful, |
|
| 10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 12 |
# GNU General Public License for more details. |
|
| 13 |
# |
|
| 14 |
# You should have received a copy of the GNU General Public License |
|
| 15 |
# along with this program; if not, write to the Free Software |
|
| 16 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
| 17 |
|
|
| 18 |
require File.expand_path('../../../test_helper', __FILE__)
|
|
| 19 |
|
|
| 20 |
class RoutingMyTest < ActionController::IntegrationTest |
|
| 21 |
def test_my |
|
| 22 |
["get", "post"].each do |method| |
|
| 23 |
assert_routing( |
|
| 24 |
{ :method => method, :path => "/my/account" },
|
|
| 25 |
{ :controller => 'my', :action => 'account' }
|
|
| 26 |
) |
|
| 27 |
end |
|
| 28 |
["get", "post"].each do |method| |
|
| 29 |
assert_routing( |
|
| 30 |
{ :method => method, :path => "/my/account/destroy" },
|
|
| 31 |
{ :controller => 'my', :action => 'destroy' }
|
|
| 32 |
) |
|
| 33 |
end |
|
| 34 |
assert_routing( |
|
| 35 |
{ :method => 'get', :path => "/my/page" },
|
|
| 36 |
{ :controller => 'my', :action => 'page' }
|
|
| 37 |
) |
|
| 38 |
assert_routing( |
|
| 39 |
{ :method => 'get', :path => "/my" },
|
|
| 40 |
{ :controller => 'my', :action => 'index' }
|
|
| 41 |
) |
|
| 42 |
assert_routing( |
|
| 43 |
{ :method => 'post', :path => "/my/reset_rss_key" },
|
|
| 44 |
{ :controller => 'my', :action => 'reset_rss_key' }
|
|
| 45 |
) |
|
| 46 |
assert_routing( |
|
| 47 |
{ :method => 'post', :path => "/my/reset_api_key" },
|
|
| 48 |
{ :controller => 'my', :action => 'reset_api_key' }
|
|
| 49 |
) |
|
| 50 |
["get", "post"].each do |method| |
|
| 51 |
assert_routing( |
|
| 52 |
{ :method => method, :path => "/my/password" },
|
|
| 53 |
{ :controller => 'my', :action => 'password' }
|
|
| 54 |
) |
|
| 55 |
end |
|
| 56 |
assert_routing( |
|
| 57 |
{ :method => 'get', :path => "/my/page_layout" },
|
|
| 58 |
{ :controller => 'my', :action => 'page_layout' }
|
|
| 59 |
) |
|
| 60 |
assert_routing( |
|
| 61 |
{ :method => 'post', :path => "/my/add_block" },
|
|
| 62 |
{ :controller => 'my', :action => 'add_block' }
|
|
| 63 |
) |
|
| 64 |
assert_routing( |
|
| 65 |
{ :method => 'post', :path => "/my/remove_block" },
|
|
| 66 |
{ :controller => 'my', :action => 'remove_block' }
|
|
| 67 |
) |
|
| 68 |
assert_routing( |
|
| 69 |
{ :method => 'post', :path => "/my/order_blocks" },
|
|
| 70 |
{ :controller => 'my', :action => 'order_blocks' }
|
|
| 71 |
) |
|
| 72 |
end |
|
| 73 |
end |
|
| .svn/pristine/09/09e163f7a5ba48f41a7d0433361b8d9b46760493.svn-base | ||
|---|---|---|
| 1 |
<%= error_messages_for 'query' %> |
|
| 2 |
|
|
| 3 |
<div class="box"> |
|
| 4 |
<div class="tabular"> |
|
| 5 |
<p><label for="query_name"><%=l(:field_name)%></label> |
|
| 6 |
<%= text_field 'query', 'name', :size => 80 %></p> |
|
| 7 |
|
|
| 8 |
<% if User.current.admin? || User.current.allowed_to?(:manage_public_queries, @project) %> |
|
| 9 |
<p><label for="query_is_public"><%=l(:field_is_public)%></label> |
|
| 10 |
<%= check_box 'query', 'is_public', |
|
| 11 |
:onchange => (User.current.admin? ? nil : 'if (this.checked) {$("#query_is_for_all").removeAttr("checked"); $("#query_is_for_all").attr("disabled", true);} else {$("#query_is_for_all").removeAttr("disabled");}') %></p>
|
|
| 12 |
<% end %> |
|
| 13 |
|
|
| 14 |
<p><label for="query_is_for_all"><%=l(:field_is_for_all)%></label> |
|
| 15 |
<%= check_box_tag 'query_is_for_all', 1, @query.project.nil?, |
|
| 16 |
:disabled => (!@query.new_record? && (@query.project.nil? || (@query.is_public? && !User.current.admin?))) %></p> |
|
| 17 |
|
|
| 18 |
<p><label for="query_default_columns"><%=l(:label_default_columns)%></label> |
|
| 19 |
<%= check_box_tag 'default_columns', 1, @query.has_default_columns?, :id => 'query_default_columns', |
|
| 20 |
:onclick => 'if (this.checked) {$("#columns").hide();} else {$("#columns").show();}' %></p>
|
|
| 21 |
|
|
| 22 |
<p><label for="query_group_by"><%= l(:field_group_by) %></label> |
|
| 23 |
<%= select 'query', 'group_by', @query.groupable_columns.collect {|c| [c.caption, c.name.to_s]}, :include_blank => true %></p>
|
|
| 24 |
|
|
| 25 |
<p><label><%= l(:button_show) %></label> |
|
| 26 |
<%= available_block_columns_tags(@query) %></p> |
|
| 27 |
</div> |
|
| 28 |
|
|
| 29 |
<fieldset id="filters"><legend><%= l(:label_filter_plural) %></legend> |
|
| 30 |
<%= render :partial => 'queries/filters', :locals => {:query => query}%>
|
|
| 31 |
</fieldset> |
|
| 32 |
|
|
| 33 |
<fieldset><legend><%= l(:label_sort) %></legend> |
|
| 34 |
<% 3.times do |i| %> |
|
| 35 |
<%= i+1 %>: |
|
| 36 |
<%= label_tag "query_sort_criteria_attribute_" + i.to_s, |
|
| 37 |
l(:description_query_sort_criteria_attribute), :class => "hidden-for-sighted" %> |
|
| 38 |
<%= select_tag("query[sort_criteria][#{i}][]",
|
|
| 39 |
options_for_select([[]] + query.available_columns.select(&:sortable?).collect {|column| [column.caption, column.name.to_s]}, @query.sort_criteria_key(i)),
|
|
| 40 |
:id => "query_sort_criteria_attribute_" + i.to_s)%> |
|
| 41 |
<%= label_tag "query_sort_criteria_direction_" + i.to_s, |
|
| 42 |
l(:description_query_sort_criteria_direction), :class => "hidden-for-sighted" %> |
|
| 43 |
<%= select_tag("query[sort_criteria][#{i}][]",
|
|
| 44 |
options_for_select([[], [l(:label_ascending), 'asc'], [l(:label_descending), 'desc']], @query.sort_criteria_order(i)), |
|
| 45 |
:id => "query_sort_criteria_direction_" + i.to_s) %> |
|
| 46 |
<br /> |
|
| 47 |
<% end %> |
|
| 48 |
</fieldset> |
|
| 49 |
|
|
| 50 |
<%= content_tag 'fieldset', :id => 'columns', :style => (query.has_default_columns? ? 'display:none;' : nil) do %> |
|
| 51 |
<legend><%= l(:field_column_names) %></legend> |
|
| 52 |
<%= render_query_columns_selection(query) %> |
|
| 53 |
<% end %> |
|
| 54 |
|
|
| 55 |
</div> |
|
| .svn/pristine/09/09eb85d785f24ac92c1ca5060b63ab8922db4494.svn-base | ||
|---|---|---|
| 1 |
# Redmine - project management software |
|
| 2 |
# Copyright (C) 2006-2013 Jean-Philippe Lang |
|
| 3 |
# |
|
| 4 |
# This program is free software; you can redistribute it and/or |
|
| 5 |
# modify it under the terms of the GNU General Public License |
|
| 6 |
# as published by the Free Software Foundation; either version 2 |
|
| 7 |
# of the License, or (at your option) any later version. |
|
| 8 |
# |
|
| 9 |
# This program is distributed in the hope that it will be useful, |
|
| 10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 12 |
# GNU General Public License for more details. |
|
| 13 |
# |
|
| 14 |
# You should have received a copy of the GNU General Public License |
|
| 15 |
# along with this program; if not, write to the Free Software |
|
| 16 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
| 17 |
|
|
| 18 |
class Mailer < ActionMailer::Base |
|
| 19 |
layout 'mailer' |
|
| 20 |
helper :application |
|
| 21 |
helper :issues |
|
| 22 |
helper :custom_fields |
|
| 23 |
|
|
| 24 |
include Redmine::I18n |
|
| 25 |
|
|
| 26 |
def self.default_url_options |
|
| 27 |
{ :host => Setting.host_name, :protocol => Setting.protocol }
|
|
| 28 |
end |
|
| 29 |
|
|
| 30 |
# Builds a Mail::Message object used to email recipients of the added issue. |
|
| 31 |
# |
|
| 32 |
# Example: |
|
| 33 |
# issue_add(issue) => Mail::Message object |
|
| 34 |
# Mailer.issue_add(issue).deliver => sends an email to issue recipients |
|
| 35 |
def issue_add(issue) |
|
| 36 |
redmine_headers 'Project' => issue.project.identifier, |
|
| 37 |
'Issue-Id' => issue.id, |
|
| 38 |
'Issue-Author' => issue.author.login |
|
| 39 |
redmine_headers 'Issue-Assignee' => issue.assigned_to.login if issue.assigned_to |
|
| 40 |
message_id issue |
|
| 41 |
@author = issue.author |
|
| 42 |
@issue = issue |
|
| 43 |
@issue_url = url_for(:controller => 'issues', :action => 'show', :id => issue) |
|
| 44 |
recipients = issue.recipients |
|
| 45 |
cc = issue.watcher_recipients - recipients |
|
| 46 |
mail :to => recipients, |
|
| 47 |
:cc => cc, |
|
| 48 |
:subject => "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] (#{issue.status.name}) #{issue.subject}"
|
|
| 49 |
end |
|
| 50 |
|
|
| 51 |
# Builds a Mail::Message object used to email recipients of the edited issue. |
|
| 52 |
# |
|
| 53 |
# Example: |
|
| 54 |
# issue_edit(journal) => Mail::Message object |
|
| 55 |
# Mailer.issue_edit(journal).deliver => sends an email to issue recipients |
|
| 56 |
def issue_edit(journal) |
|
| 57 |
issue = journal.journalized.reload |
|
| 58 |
redmine_headers 'Project' => issue.project.identifier, |
|
| 59 |
'Issue-Id' => issue.id, |
|
| 60 |
'Issue-Author' => issue.author.login |
|
| 61 |
redmine_headers 'Issue-Assignee' => issue.assigned_to.login if issue.assigned_to |
|
| 62 |
message_id journal |
|
| 63 |
references issue |
|
| 64 |
@author = journal.user |
|
| 65 |
recipients = journal.recipients |
|
| 66 |
# Watchers in cc |
|
| 67 |
cc = journal.watcher_recipients - recipients |
|
| 68 |
s = "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] "
|
|
| 69 |
s << "(#{issue.status.name}) " if journal.new_value_for('status_id')
|
|
| 70 |
s << issue.subject |
|
| 71 |
@issue = issue |
|
| 72 |
@journal = journal |
|
| 73 |
@issue_url = url_for(:controller => 'issues', :action => 'show', :id => issue, :anchor => "change-#{journal.id}")
|
|
| 74 |
mail :to => recipients, |
|
| 75 |
:cc => cc, |
|
| 76 |
:subject => s |
|
| 77 |
end |
|
| 78 |
|
|
| 79 |
def reminder(user, issues, days) |
|
| 80 |
set_language_if_valid user.language |
|
| 81 |
@issues = issues |
|
| 82 |
@days = days |
|
| 83 |
@issues_url = url_for(:controller => 'issues', :action => 'index', |
|
| 84 |
:set_filter => 1, :assigned_to_id => user.id, |
|
| 85 |
:sort => 'due_date:asc') |
|
| 86 |
mail :to => user.mail, |
|
| 87 |
:subject => l(:mail_subject_reminder, :count => issues.size, :days => days) |
|
| 88 |
end |
|
| 89 |
|
|
| 90 |
# Builds a Mail::Message object used to email users belonging to the added document's project. |
|
| 91 |
# |
|
| 92 |
# Example: |
|
| 93 |
# document_added(document) => Mail::Message object |
|
| 94 |
# Mailer.document_added(document).deliver => sends an email to the document's project recipients |
|
| 95 |
def document_added(document) |
|
| 96 |
redmine_headers 'Project' => document.project.identifier |
|
| 97 |
@author = User.current |
|
| 98 |
@document = document |
|
| 99 |
@document_url = url_for(:controller => 'documents', :action => 'show', :id => document) |
|
| 100 |
mail :to => document.recipients, |
|
| 101 |
:subject => "[#{document.project.name}] #{l(:label_document_new)}: #{document.title}"
|
|
| 102 |
end |
|
| 103 |
|
|
| 104 |
# Builds a Mail::Message object used to email recipients of a project when an attachements are added. |
|
| 105 |
# |
|
| 106 |
# Example: |
|
| 107 |
# attachments_added(attachments) => Mail::Message object |
|
| 108 |
# Mailer.attachments_added(attachments).deliver => sends an email to the project's recipients |
|
| 109 |
def attachments_added(attachments) |
|
| 110 |
container = attachments.first.container |
|
| 111 |
added_to = '' |
|
| 112 |
added_to_url = '' |
|
| 113 |
@author = attachments.first.author |
|
| 114 |
case container.class.name |
|
| 115 |
when 'Project' |
|
| 116 |
added_to_url = url_for(:controller => 'files', :action => 'index', :project_id => container) |
|
| 117 |
added_to = "#{l(:label_project)}: #{container}"
|
|
| 118 |
recipients = container.project.notified_users.select {|user| user.allowed_to?(:view_files, container.project)}.collect {|u| u.mail}
|
|
| 119 |
when 'Version' |
|
| 120 |
added_to_url = url_for(:controller => 'files', :action => 'index', :project_id => container.project) |
|
| 121 |
added_to = "#{l(:label_version)}: #{container.name}"
|
|
| 122 |
recipients = container.project.notified_users.select {|user| user.allowed_to?(:view_files, container.project)}.collect {|u| u.mail}
|
|
| 123 |
when 'Document' |
|
| 124 |
added_to_url = url_for(:controller => 'documents', :action => 'show', :id => container.id) |
|
| 125 |
added_to = "#{l(:label_document)}: #{container.title}"
|
|
| 126 |
recipients = container.recipients |
|
| 127 |
end |
|
| 128 |
redmine_headers 'Project' => container.project.identifier |
|
| 129 |
@attachments = attachments |
|
| 130 |
@added_to = added_to |
|
| 131 |
@added_to_url = added_to_url |
|
| 132 |
mail :to => recipients, |
|
| 133 |
:subject => "[#{container.project.name}] #{l(:label_attachment_new)}"
|
|
| 134 |
end |
|
| 135 |
|
|
| 136 |
# Builds a Mail::Message object used to email recipients of a news' project when a news item is added. |
|
| 137 |
# |
|
| 138 |
# Example: |
|
| 139 |
# news_added(news) => Mail::Message object |
|
| 140 |
# Mailer.news_added(news).deliver => sends an email to the news' project recipients |
|
| 141 |
def news_added(news) |
|
| 142 |
redmine_headers 'Project' => news.project.identifier |
|
| 143 |
@author = news.author |
|
| 144 |
message_id news |
|
| 145 |
@news = news |
|
| 146 |
@news_url = url_for(:controller => 'news', :action => 'show', :id => news) |
|
| 147 |
mail :to => news.recipients, |
|
| 148 |
:subject => "[#{news.project.name}] #{l(:label_news)}: #{news.title}"
|
|
| 149 |
end |
|
| 150 |
|
|
| 151 |
# Builds a Mail::Message object used to email recipients of a news' project when a news comment is added. |
|
| 152 |
# |
|
| 153 |
# Example: |
|
| 154 |
# news_comment_added(comment) => Mail::Message object |
|
| 155 |
# Mailer.news_comment_added(comment) => sends an email to the news' project recipients |
|
| 156 |
def news_comment_added(comment) |
|
| 157 |
news = comment.commented |
|
| 158 |
redmine_headers 'Project' => news.project.identifier |
|
| 159 |
@author = comment.author |
|
| 160 |
message_id comment |
|
| 161 |
@news = news |
|
| 162 |
@comment = comment |
|
| 163 |
@news_url = url_for(:controller => 'news', :action => 'show', :id => news) |
|
| 164 |
mail :to => news.recipients, |
|
| 165 |
:cc => news.watcher_recipients, |
|
| 166 |
:subject => "Re: [#{news.project.name}] #{l(:label_news)}: #{news.title}"
|
|
| 167 |
end |
|
| 168 |
|
|
| 169 |
# Builds a Mail::Message object used to email the recipients of the specified message that was posted. |
|
| 170 |
# |
|
| 171 |
# Example: |
|
| 172 |
# message_posted(message) => Mail::Message object |
|
| 173 |
# Mailer.message_posted(message).deliver => sends an email to the recipients |
|
| 174 |
def message_posted(message) |
|
| 175 |
redmine_headers 'Project' => message.project.identifier, |
|
| 176 |
'Topic-Id' => (message.parent_id || message.id) |
|
| 177 |
@author = message.author |
|
| 178 |
message_id message |
|
| 179 |
references message.parent unless message.parent.nil? |
|
| 180 |
recipients = message.recipients |
|
| 181 |
cc = ((message.root.watcher_recipients + message.board.watcher_recipients).uniq - recipients) |
|
| 182 |
@message = message |
|
| 183 |
@message_url = url_for(message.event_url) |
|
| 184 |
mail :to => recipients, |
|
| 185 |
:cc => cc, |
|
| 186 |
:subject => "[#{message.board.project.name} - #{message.board.name} - msg#{message.root.id}] #{message.subject}"
|
|
| 187 |
end |
|
| 188 |
|
|
| 189 |
# Builds a Mail::Message object used to email the recipients of a project of the specified wiki content was added. |
|
| 190 |
# |
|
| 191 |
# Example: |
|
| 192 |
# wiki_content_added(wiki_content) => Mail::Message object |
|
| 193 |
# Mailer.wiki_content_added(wiki_content).deliver => sends an email to the project's recipients |
|
| 194 |
def wiki_content_added(wiki_content) |
|
| 195 |
redmine_headers 'Project' => wiki_content.project.identifier, |
|
| 196 |
'Wiki-Page-Id' => wiki_content.page.id |
|
| 197 |
@author = wiki_content.author |
|
| 198 |
message_id wiki_content |
|
| 199 |
recipients = wiki_content.recipients |
|
| 200 |
cc = wiki_content.page.wiki.watcher_recipients - recipients |
|
| 201 |
@wiki_content = wiki_content |
|
| 202 |
@wiki_content_url = url_for(:controller => 'wiki', :action => 'show', |
|
| 203 |
:project_id => wiki_content.project, |
|
| 204 |
:id => wiki_content.page.title) |
|
| 205 |
mail :to => recipients, |
|
| 206 |
:cc => cc, |
|
| 207 |
:subject => "[#{wiki_content.project.name}] #{l(:mail_subject_wiki_content_added, :id => wiki_content.page.pretty_title)}"
|
|
| 208 |
end |
|
| 209 |
|
|
| 210 |
# Builds a Mail::Message object used to email the recipients of a project of the specified wiki content was updated. |
|
| 211 |
# |
|
| 212 |
# Example: |
|
| 213 |
# wiki_content_updated(wiki_content) => Mail::Message object |
|
| 214 |
# Mailer.wiki_content_updated(wiki_content).deliver => sends an email to the project's recipients |
|
| 215 |
def wiki_content_updated(wiki_content) |
|
| 216 |
redmine_headers 'Project' => wiki_content.project.identifier, |
|
| 217 |
'Wiki-Page-Id' => wiki_content.page.id |
|
| 218 |
@author = wiki_content.author |
|
| 219 |
message_id wiki_content |
|
| 220 |
recipients = wiki_content.recipients |
|
| 221 |
cc = wiki_content.page.wiki.watcher_recipients + wiki_content.page.watcher_recipients - recipients |
|
| 222 |
@wiki_content = wiki_content |
|
| 223 |
@wiki_content_url = url_for(:controller => 'wiki', :action => 'show', |
|
| 224 |
:project_id => wiki_content.project, |
|
| 225 |
:id => wiki_content.page.title) |
|
| 226 |
@wiki_diff_url = url_for(:controller => 'wiki', :action => 'diff', |
|
| 227 |
:project_id => wiki_content.project, :id => wiki_content.page.title, |
|
| 228 |
:version => wiki_content.version) |
|
| 229 |
mail :to => recipients, |
|
| 230 |
:cc => cc, |
|
| 231 |
:subject => "[#{wiki_content.project.name}] #{l(:mail_subject_wiki_content_updated, :id => wiki_content.page.pretty_title)}"
|
|
| 232 |
end |
|
| 233 |
|
|
| 234 |
# Builds a Mail::Message object used to email the specified user their account information. |
|
| 235 |
# |
|
| 236 |
# Example: |
|
| 237 |
# account_information(user, password) => Mail::Message object |
|
| 238 |
# Mailer.account_information(user, password).deliver => sends account information to the user |
|
| 239 |
def account_information(user, password) |
|
| 240 |
set_language_if_valid user.language |
|
| 241 |
@user = user |
|
| 242 |
@password = password |
|
| 243 |
@login_url = url_for(:controller => 'account', :action => 'login') |
|
| 244 |
mail :to => user.mail, |
|
| 245 |
:subject => l(:mail_subject_register, Setting.app_title) |
|
| 246 |
end |
|
| 247 |
|
|
| 248 |
# Builds a Mail::Message object used to email all active administrators of an account activation request. |
|
| 249 |
# |
|
| 250 |
# Example: |
|
| 251 |
# account_activation_request(user) => Mail::Message object |
|
| 252 |
# Mailer.account_activation_request(user).deliver => sends an email to all active administrators |
|
| 253 |
def account_activation_request(user) |
|
| 254 |
# Send the email to all active administrators |
|
| 255 |
recipients = User.active.where(:admin => true).all.collect { |u| u.mail }.compact
|
|
| 256 |
@user = user |
|
| 257 |
@url = url_for(:controller => 'users', :action => 'index', |
|
| 258 |
:status => User::STATUS_REGISTERED, |
|
| 259 |
:sort_key => 'created_on', :sort_order => 'desc') |
|
| 260 |
mail :to => recipients, |
|
| 261 |
:subject => l(:mail_subject_account_activation_request, Setting.app_title) |
|
| 262 |
end |
|
| 263 |
|
|
| 264 |
# Builds a Mail::Message object used to email the specified user that their account was activated by an administrator. |
|
| 265 |
# |
|
| 266 |
# Example: |
|
| 267 |
# account_activated(user) => Mail::Message object |
|
| 268 |
# Mailer.account_activated(user).deliver => sends an email to the registered user |
|
| 269 |
def account_activated(user) |
|
| 270 |
set_language_if_valid user.language |
|
| 271 |
@user = user |
|
| 272 |
@login_url = url_for(:controller => 'account', :action => 'login') |
|
| 273 |
mail :to => user.mail, |
|
| 274 |
:subject => l(:mail_subject_register, Setting.app_title) |
|
| 275 |
end |
|
| 276 |
|
|
| 277 |
def lost_password(token) |
|
| 278 |
set_language_if_valid(token.user.language) |
|
| 279 |
@token = token |
|
| 280 |
@url = url_for(:controller => 'account', :action => 'lost_password', :token => token.value) |
|
| 281 |
mail :to => token.user.mail, |
|
| 282 |
:subject => l(:mail_subject_lost_password, Setting.app_title) |
|
| 283 |
end |
|
| 284 |
|
|
| 285 |
def register(token) |
|
| 286 |
set_language_if_valid(token.user.language) |
|
| 287 |
@token = token |
|
| 288 |
@url = url_for(:controller => 'account', :action => 'activate', :token => token.value) |
|
| 289 |
mail :to => token.user.mail, |
|
| 290 |
:subject => l(:mail_subject_register, Setting.app_title) |
|
| 291 |
end |
|
| 292 |
|
|
| 293 |
def test_email(user) |
|
| 294 |
set_language_if_valid(user.language) |
|
| 295 |
@url = url_for(:controller => 'welcome') |
|
| 296 |
mail :to => user.mail, |
|
| 297 |
:subject => 'Redmine test' |
|
| 298 |
end |
|
| 299 |
|
|
| 300 |
# Overrides default deliver! method to prevent from sending an email |
|
| 301 |
# with no recipient, cc or bcc |
|
| 302 |
def deliver!(mail = @mail) |
|
| 303 |
set_language_if_valid @initial_language |
|
| 304 |
return false if (recipients.nil? || recipients.empty?) && |
|
| 305 |
(cc.nil? || cc.empty?) && |
|
| 306 |
(bcc.nil? || bcc.empty?) |
|
| 307 |
|
|
| 308 |
|
|
| 309 |
# Log errors when raise_delivery_errors is set to false, Rails does not |
|
| 310 |
raise_errors = self.class.raise_delivery_errors |
|
| 311 |
self.class.raise_delivery_errors = true |
|
| 312 |
begin |
|
| 313 |
return super(mail) |
|
| 314 |
rescue Exception => e |
|
| 315 |
if raise_errors |
|
| 316 |
raise e |
|
| 317 |
elsif mylogger |
|
| 318 |
mylogger.error "The following error occured while sending email notification: \"#{e.message}\". Check your configuration in config/configuration.yml."
|
|
| 319 |
end |
|
| 320 |
ensure |
|
| 321 |
self.class.raise_delivery_errors = raise_errors |
|
| 322 |
end |
|
| 323 |
end |
|
| 324 |
|
|
| 325 |
# Sends reminders to issue assignees |
|
| 326 |
# Available options: |
|
| 327 |
# * :days => how many days in the future to remind about (defaults to 7) |
|
| 328 |
# * :tracker => id of tracker for filtering issues (defaults to all trackers) |
|
| 329 |
# * :project => id or identifier of project to process (defaults to all projects) |
|
| 330 |
# * :users => array of user/group ids who should be reminded |
|
| 331 |
def self.reminders(options={})
|
|
| 332 |
days = options[:days] || 7 |
|
| 333 |
project = options[:project] ? Project.find(options[:project]) : nil |
|
| 334 |
tracker = options[:tracker] ? Tracker.find(options[:tracker]) : nil |
|
| 335 |
user_ids = options[:users] |
|
| 336 |
|
|
| 337 |
scope = Issue.open.where("#{Issue.table_name}.assigned_to_id IS NOT NULL" +
|
|
| 338 |
" AND #{Project.table_name}.status = #{Project::STATUS_ACTIVE}" +
|
|
| 339 |
" AND #{Issue.table_name}.due_date <= ?", days.day.from_now.to_date
|
|
| 340 |
) |
|
| 341 |
scope = scope.where(:assigned_to_id => user_ids) if user_ids.present? |
|
| 342 |
scope = scope.where(:project_id => project.id) if project |
|
| 343 |
scope = scope.where(:tracker_id => tracker.id) if tracker |
|
| 344 |
|
|
| 345 |
issues_by_assignee = scope.includes(:status, :assigned_to, :project, :tracker).all.group_by(&:assigned_to) |
|
| 346 |
issues_by_assignee.keys.each do |assignee| |
|
| 347 |
if assignee.is_a?(Group) |
|
| 348 |
assignee.users.each do |user| |
|
| 349 |
issues_by_assignee[user] ||= [] |
|
| 350 |
issues_by_assignee[user] += issues_by_assignee[assignee] |
|
| 351 |
end |
|
| 352 |
end |
|
| 353 |
end |
|
| 354 |
|
|
| 355 |
issues_by_assignee.each do |assignee, issues| |
|
| 356 |
reminder(assignee, issues, days).deliver if assignee.is_a?(User) && assignee.active? |
|
| 357 |
end |
|
| 358 |
end |
|
| 359 |
|
|
| 360 |
# Activates/desactivates email deliveries during +block+ |
|
| 361 |
def self.with_deliveries(enabled = true, &block) |
|
| 362 |
was_enabled = ActionMailer::Base.perform_deliveries |
|
| 363 |
ActionMailer::Base.perform_deliveries = !!enabled |
|
| 364 |
yield |
|
| 365 |
ensure |
|
| 366 |
ActionMailer::Base.perform_deliveries = was_enabled |
|
| 367 |
end |
|
| 368 |
|
|
| 369 |
# Sends emails synchronously in the given block |
|
| 370 |
def self.with_synched_deliveries(&block) |
|
| 371 |
saved_method = ActionMailer::Base.delivery_method |
|
| 372 |
if m = saved_method.to_s.match(%r{^async_(.+)$})
|
|
| 373 |
synched_method = m[1] |
|
| 374 |
ActionMailer::Base.delivery_method = synched_method.to_sym |
|
| 375 |
ActionMailer::Base.send "#{synched_method}_settings=", ActionMailer::Base.send("async_#{synched_method}_settings")
|
|
| 376 |
end |
|
| 377 |
yield |
|
| 378 |
ensure |
|
| 379 |
ActionMailer::Base.delivery_method = saved_method |
|
| 380 |
end |
|
| 381 |
|
|
| 382 |
def mail(headers={})
|
|
| 383 |
headers.merge! 'X-Mailer' => 'Redmine', |
|
| 384 |
'X-Redmine-Host' => Setting.host_name, |
|
| 385 |
'X-Redmine-Site' => Setting.app_title, |
|
| 386 |
'X-Auto-Response-Suppress' => 'OOF', |
|
| 387 |
'Auto-Submitted' => 'auto-generated', |
|
| 388 |
'From' => Setting.mail_from, |
|
| 389 |
'List-Id' => "<#{Setting.mail_from.to_s.gsub('@', '.')}>"
|
|
| 390 |
|
|
| 391 |
# Removes the author from the recipients and cc |
|
| 392 |
# if he doesn't want to receive notifications about what he does |
|
| 393 |
if @author && @author.logged? && @author.pref[:no_self_notified] |
|
| 394 |
headers[:to].delete(@author.mail) if headers[:to].is_a?(Array) |
|
| 395 |
headers[:cc].delete(@author.mail) if headers[:cc].is_a?(Array) |
|
| 396 |
end |
|
| 397 |
|
|
| 398 |
if @author && @author.logged? |
|
| 399 |
redmine_headers 'Sender' => @author.login |
|
| 400 |
end |
|
| 401 |
|
|
| 402 |
# Blind carbon copy recipients |
|
| 403 |
if Setting.bcc_recipients? |
|
| 404 |
headers[:bcc] = [headers[:to], headers[:cc]].flatten.uniq.reject(&:blank?) |
|
| 405 |
headers[:to] = nil |
|
| 406 |
headers[:cc] = nil |
|
| 407 |
end |
|
| 408 |
|
|
| 409 |
if @message_id_object |
|
| 410 |
headers[:message_id] = "<#{self.class.message_id_for(@message_id_object)}>"
|
|
| 411 |
end |
|
| 412 |
if @references_objects |
|
| 413 |
headers[:references] = @references_objects.collect {|o| "<#{self.class.message_id_for(o)}>"}.join(' ')
|
|
| 414 |
end |
|
| 415 |
|
|
| 416 |
super headers do |format| |
|
| 417 |
format.text |
|
| 418 |
format.html unless Setting.plain_text_mail? |
|
| 419 |
end |
|
| 420 |
|
|
| 421 |
set_language_if_valid @initial_language |
|
| 422 |
end |
|
| 423 |
|
|
| 424 |
def initialize(*args) |
|
| 425 |
@initial_language = current_language |
|
| 426 |
set_language_if_valid Setting.default_language |
|
| 427 |
super |
|
| 428 |
end |
|
| 429 |
|
|
| 430 |
def self.deliver_mail(mail) |
|
| 431 |
return false if mail.to.blank? && mail.cc.blank? && mail.bcc.blank? |
|
| 432 |
super |
|
| 433 |
end |
|
| 434 |
|
|
| 435 |
def self.method_missing(method, *args, &block) |
|
| 436 |
if m = method.to_s.match(%r{^deliver_(.+)$})
|
|
| 437 |
ActiveSupport::Deprecation.warn "Mailer.deliver_#{m[1]}(*args) is deprecated. Use Mailer.#{m[1]}(*args).deliver instead."
|
|
| 438 |
send(m[1], *args).deliver |
|
| 439 |
else |
|
| 440 |
super |
|
| 441 |
end |
|
| 442 |
end |
|
| 443 |
|
|
| 444 |
private |
|
| 445 |
|
|
| 446 |
# Appends a Redmine header field (name is prepended with 'X-Redmine-') |
|
| 447 |
def redmine_headers(h) |
|
| 448 |
h.each { |k,v| headers["X-Redmine-#{k}"] = v.to_s }
|
|
| 449 |
end |
|
| 450 |
|
|
| 451 |
# Returns a predictable Message-Id for the given object |
|
| 452 |
def self.message_id_for(object) |
|
| 453 |
# id + timestamp should reduce the odds of a collision |
|
| 454 |
# as far as we don't send multiple emails for the same object |
|
| 455 |
timestamp = object.send(object.respond_to?(:created_on) ? :created_on : :updated_on) |
|
| 456 |
hash = "redmine.#{object.class.name.demodulize.underscore}-#{object.id}.#{timestamp.strftime("%Y%m%d%H%M%S")}"
|
|
| 457 |
host = Setting.mail_from.to_s.gsub(%r{^.*@}, '')
|
|
| 458 |
host = "#{::Socket.gethostname}.redmine" if host.empty?
|
|
| 459 |
"#{hash}@#{host}"
|
|
| 460 |
end |
|
| 461 |
|
|
| 462 |
def message_id(object) |
|
| 463 |
@message_id_object = object |
|
| 464 |
end |
|
| 465 |
|
|
| 466 |
def references(object) |
|
| 467 |
@references_objects ||= [] |
|
| 468 |
@references_objects << object |
|
| 469 |
end |
|
| 470 |
|
|
| 471 |
def mylogger |
|
| 472 |
Rails.logger |
|
| 473 |
end |
|
| 474 |
end |
|
| .svn/pristine/09/09ee2f48a5aafa2ec6da3a021e076cc86af61f01.svn-base | ||
|---|---|---|
| 1 |
<h2><%= l(:label_board_new) %></h2> |
|
| 2 |
|
|
| 3 |
<% labelled_tabular_form_for :board, @board, :url => {:action => 'new'} do |f| %>
|
|
| 4 |
<%= render :partial => 'form', :locals => {:f => f} %>
|
|
| 5 |
<%= submit_tag l(:button_create) %> |
|
| 6 |
<% end %> |
|
| .svn/pristine/09/09fd6db0926bf35a4db846796898a3efe70dfa6f.svn-base | ||
|---|---|---|
| 1 |
<table class="list transitions-<%= name %>"> |
|
| 2 |
<thead> |
|
| 3 |
<tr> |
|
| 4 |
<th align="left"> |
|
| 5 |
<%= link_to_function(image_tag('toggle_check.png'), "toggleCheckboxesBySelector('table.transitions-#{name} input')",
|
|
| 6 |
:title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}") %>
|
|
| 7 |
<%=l(:label_current_status)%> |
|
| 8 |
</th> |
|
| 9 |
<th align="center" colspan="<%= @statuses.length %>"><%=l(:label_new_statuses_allowed)%></th> |
|
| 10 |
</tr> |
|
| 11 |
<tr> |
|
| 12 |
<td></td> |
|
| 13 |
<% for new_status in @statuses %> |
|
| 14 |
<td width="<%= 75 / @statuses.size %>%" align="center"> |
|
| 15 |
<%= link_to_function(image_tag('toggle_check.png'), "toggleCheckboxesBySelector('table.transitions-#{name} input.new-status-#{new_status.id}')",
|
|
| 16 |
:title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}") %>
|
|
| 17 |
<%=h new_status.name %> |
|
| 18 |
</td> |
|
| 19 |
<% end %> |
|
| 20 |
</tr> |
|
| 21 |
</thead> |
|
| 22 |
<tbody> |
|
| 23 |
<% for old_status in @statuses %> |
|
| 24 |
<tr class="<%= cycle("odd", "even") %>">
|
|
| 25 |
<td> |
|
| 26 |
<%= link_to_function(image_tag('toggle_check.png'), "toggleCheckboxesBySelector('table.transitions-#{name} input.old-status-#{old_status.id}')",
|
|
| 27 |
:title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}") %>
|
|
| 28 |
|
|
| 29 |
<%=h old_status.name %> |
|
| 30 |
</td> |
|
| 31 |
<% for new_status in @statuses -%> |
|
| 32 |
<td align="center"> |
|
| 33 |
<%= check_box_tag "issue_status[#{ old_status.id }][#{new_status.id}][]", name, workflows.detect {|w| w.old_status_id == old_status.id && w.new_status_id == new_status.id},
|
|
| 34 |
:class => "old-status-#{old_status.id} new-status-#{new_status.id}" %>
|
|
| 35 |
</td> |
|
| 36 |
<% end -%> |
|
| 37 |
</tr> |
|
| 38 |
<% end %> |
|
| 39 |
</tbody> |
|
| 40 |
</table> |
|
Also available in: Unified diff