@@ -29,11 +29,11 class MailHandler < ActionMailer::Base | |||||
29 |
|
29 | |||
30 | options[:issue] ||= {} |
|
30 | options[:issue] ||= {} | |
31 |
|
31 | |||
|
32 | options[:allow_override] ||= [] | |||
32 | if options[:allow_override].is_a?(String) |
|
33 | if options[:allow_override].is_a?(String) | |
33 |
options[:allow_override] = options[:allow_override].split(',') |
|
34 | options[:allow_override] = options[:allow_override].split(',') | |
34 | end |
|
35 | end | |
35 | options[:allow_override] ||= [] |
|
36 | options[:allow_override].map! {|s| s.strip.downcase.gsub(/\s+/, '_')} | |
36 | options[:allow_override].map!(&:downcase) |
|
|||
37 | # Project needs to be overridable if not specified |
|
37 | # Project needs to be overridable if not specified | |
38 | options[:allow_override] << 'project' unless options[:issue].has_key?(:project) |
|
38 | options[:allow_override] << 'project' unless options[:issue].has_key?(:project) | |
39 |
|
39 | |||
@@ -327,8 +327,11 class MailHandler < ActionMailer::Base | |||||
327 | @keywords[attr] |
|
327 | @keywords[attr] | |
328 | else |
|
328 | else | |
329 | @keywords[attr] = begin |
|
329 | @keywords[attr] = begin | |
330 | if (options[:override] || handler_options[:allow_override].include?(attr.to_s.downcase)) && |
|
330 | override = options.key?(:override) ? | |
331 | (v = extract_keyword!(cleaned_up_text_body, attr, options[:format])) |
|
331 | options[:override] : | |
|
332 | (handler_options[:allow_override] & [attr.to_s.downcase.gsub(/\s+/, '_'), 'all']).present? | |||
|
333 | ||||
|
334 | if override && (v = extract_keyword!(cleaned_up_text_body, attr, options[:format])) | |||
332 | v |
|
335 | v | |
333 | elsif !handler_options[:issue][attr].blank? |
|
336 | elsif !handler_options[:issue][attr].blank? | |
334 | handler_options[:issue][attr] |
|
337 | handler_options[:issue][attr] |
@@ -21,37 +21,7 namespace :redmine do | |||||
21 | desc <<-END_DESC |
|
21 | desc <<-END_DESC | |
22 | Read an email from standard input. |
|
22 | Read an email from standard input. | |
23 |
|
23 | |||
24 | General options: |
|
24 | See redmine:email:receive_imap for more options and examples. | |
25 | unknown_user=ACTION how to handle emails from an unknown user |
|
|||
26 | ACTION can be one of the following values: |
|
|||
27 | ignore: email is ignored (default) |
|
|||
28 | accept: accept as anonymous user |
|
|||
29 | create: create a user account |
|
|||
30 | no_permission_check=1 disable permission checking when receiving |
|
|||
31 | the email |
|
|||
32 | no_account_notice=1 disable new user account notification |
|
|||
33 | default_group=foo,bar adds created user to foo and bar groups |
|
|||
34 |
|
||||
35 | Issue attributes control options: |
|
|||
36 | project=PROJECT identifier of the target project |
|
|||
37 | status=STATUS name of the target status |
|
|||
38 | tracker=TRACKER name of the target tracker |
|
|||
39 | category=CATEGORY name of the target category |
|
|||
40 | priority=PRIORITY name of the target priority |
|
|||
41 | allow_override=ATTRS allow email content to override attributes |
|
|||
42 | specified by previous options |
|
|||
43 | ATTRS is a comma separated list of attributes |
|
|||
44 |
|
||||
45 | Examples: |
|
|||
46 | # No project specified. Emails MUST contain the 'Project' keyword: |
|
|||
47 | rake redmine:email:read RAILS_ENV="production" < raw_email |
|
|||
48 |
|
||||
49 | # Fixed project and default tracker specified, but emails can override |
|
|||
50 | # both tracker and priority attributes: |
|
|||
51 | rake redmine:email:read RAILS_ENV="production" \\ |
|
|||
52 | project=foo \\ |
|
|||
53 | tracker=bug \\ |
|
|||
54 | allow_override=tracker,priority < raw_email |
|
|||
55 | END_DESC |
|
25 | END_DESC | |
56 |
|
26 | |||
57 | task :read => :environment do |
|
27 | task :read => :environment do | |
@@ -63,7 +33,21 END_DESC | |||||
63 | desc <<-END_DESC |
|
33 | desc <<-END_DESC | |
64 | Read emails from an IMAP server. |
|
34 | Read emails from an IMAP server. | |
65 |
|
35 | |||
66 | General options: |
|
36 | Available IMAP options: | |
|
37 | host=HOST IMAP server host (default: 127.0.0.1) | |||
|
38 | port=PORT IMAP server port (default: 143) | |||
|
39 | ssl=SSL Use SSL/TLS? (default: false) | |||
|
40 | starttls=STARTTLS Use STARTTLS? (default: false) | |||
|
41 | username=USERNAME IMAP account | |||
|
42 | password=PASSWORD IMAP password | |||
|
43 | folder=FOLDER IMAP folder to read (default: INBOX) | |||
|
44 | ||||
|
45 | Processed emails control options: | |||
|
46 | move_on_success=MAILBOX move emails that were successfully received | |||
|
47 | to MAILBOX instead of deleting them | |||
|
48 | move_on_failure=MAILBOX move emails that were ignored to MAILBOX | |||
|
49 | ||||
|
50 | User and permissions options: | |||
67 | unknown_user=ACTION how to handle emails from an unknown user |
|
51 | unknown_user=ACTION how to handle emails from an unknown user | |
68 | ACTION can be one of the following values: |
|
52 | ACTION can be one of the following values: | |
69 | ignore: email is ignored (default) |
|
53 | ignore: email is ignored (default) | |
@@ -74,15 +58,6 General options: | |||||
74 | no_account_notice=1 disable new user account notification |
|
58 | no_account_notice=1 disable new user account notification | |
75 | default_group=foo,bar adds created user to foo and bar groups |
|
59 | default_group=foo,bar adds created user to foo and bar groups | |
76 |
|
60 | |||
77 | Available IMAP options: |
|
|||
78 | host=HOST IMAP server host (default: 127.0.0.1) |
|
|||
79 | port=PORT IMAP server port (default: 143) |
|
|||
80 | ssl=SSL Use SSL/TLS? (default: false) |
|
|||
81 | starttls=STARTTLS Use STARTTLS? (default: false) |
|
|||
82 | username=USERNAME IMAP account |
|
|||
83 | password=PASSWORD IMAP password |
|
|||
84 | folder=FOLDER IMAP folder to read (default: INBOX) |
|
|||
85 |
|
||||
86 | Issue attributes control options: |
|
61 | Issue attributes control options: | |
87 | project=PROJECT identifier of the target project |
|
62 | project=PROJECT identifier of the target project | |
88 | status=STATUS name of the target status |
|
63 | status=STATUS name of the target status | |
@@ -90,14 +65,23 Issue attributes control options: | |||||
90 | category=CATEGORY name of the target category |
|
65 | category=CATEGORY name of the target category | |
91 | priority=PRIORITY name of the target priority |
|
66 | priority=PRIORITY name of the target priority | |
92 | private create new issues as private |
|
67 | private create new issues as private | |
93 |
allow_override=ATTRS allow email content to |
|
68 | allow_override=ATTRS allow email content to set attributes values | |
94 | specified by previous options |
|
|||
95 | ATTRS is a comma separated list of attributes |
|
69 | ATTRS is a comma separated list of attributes | |
|
70 | or 'all' to allow all attributes to be overridable | |||
|
71 | (see below for details) | |||
96 |
|
72 | |||
97 | Processed emails control options: |
|
73 | Overrides: | |
98 | move_on_success=MAILBOX move emails that were successfully received |
|
74 | ATTRS is a comma separated list of attributes among: | |
99 | to MAILBOX instead of deleting them |
|
75 | * project, tracker, status, priority, category, assigned_to, fixed_version, | |
100 | move_on_failure=MAILBOX move emails that were ignored to MAILBOX |
|
76 | start_date, due_date, estimated_hours, done_ratio | |
|
77 | * custom fields names with underscores instead of spaces (case insensitive) | |||
|
78 | ||||
|
79 | Example: allow_override=project,priority,my_custom_field | |||
|
80 | ||||
|
81 | If the project option is not set, project is overridable by default for | |||
|
82 | emails that create new issues. | |||
|
83 | ||||
|
84 | You can use allow_override=all to allow all attributes to be overridable. | |||
101 |
|
85 | |||
102 | Examples: |
|
86 | Examples: | |
103 | # No project specified. Emails MUST contain the 'Project' keyword: |
|
87 | # No project specified. Emails MUST contain the 'Project' keyword: |
@@ -40,10 +40,9 class MailHandlerTest < ActiveSupport::TestCase | |||||
40 | Setting.clear_cache |
|
40 | Setting.clear_cache | |
41 | end |
|
41 | end | |
42 |
|
42 | |||
43 | def test_add_issue |
|
43 | def test_add_issue_with_specific_overrides | |
44 | ActionMailer::Base.deliveries.clear |
|
44 | ActionMailer::Base.deliveries.clear | |
45 | lft1 = new_issue_lft |
|
45 | lft1 = new_issue_lft | |
46 | # This email contains: 'Project: onlinestore' |
|
|||
47 | issue = submit_email('ticket_on_given_project.eml', |
|
46 | issue = submit_email('ticket_on_given_project.eml', | |
48 | :allow_override => ['status', 'start_date', 'due_date', 'assigned_to', 'fixed_version', 'estimated_hours', 'done_ratio'] |
|
47 | :allow_override => ['status', 'start_date', 'due_date', 'assigned_to', 'fixed_version', 'estimated_hours', 'done_ratio'] | |
49 | ) |
|
48 | ) | |
@@ -74,6 +73,46 class MailHandlerTest < ActiveSupport::TestCase | |||||
74 | assert mail.subject.include?('New ticket on a given project') |
|
73 | assert mail.subject.include?('New ticket on a given project') | |
75 | end |
|
74 | end | |
76 |
|
75 | |||
|
76 | def test_add_issue_with_all_overrides | |||
|
77 | ActionMailer::Base.deliveries.clear | |||
|
78 | lft1 = new_issue_lft | |||
|
79 | issue = submit_email('ticket_on_given_project.eml', :allow_override => 'all') | |||
|
80 | assert issue.is_a?(Issue) | |||
|
81 | assert !issue.new_record? | |||
|
82 | issue.reload | |||
|
83 | assert_equal Project.find(2), issue.project | |||
|
84 | assert_equal issue.project.trackers.first, issue.tracker | |||
|
85 | assert_equal IssueStatus.find_by_name('Resolved'), issue.status | |||
|
86 | assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.') | |||
|
87 | assert_equal '2010-01-01', issue.start_date.to_s | |||
|
88 | assert_equal '2010-12-31', issue.due_date.to_s | |||
|
89 | assert_equal User.find_by_login('jsmith'), issue.assigned_to | |||
|
90 | assert_equal Version.find_by_name('Alpha'), issue.fixed_version | |||
|
91 | assert_equal 2.5, issue.estimated_hours | |||
|
92 | assert_equal 30, issue.done_ratio | |||
|
93 | end | |||
|
94 | ||||
|
95 | def test_add_issue_without_overrides_should_ignore_attributes | |||
|
96 | WorkflowRule.delete_all | |||
|
97 | issue = submit_email('ticket_on_given_project.eml') | |||
|
98 | assert issue.is_a?(Issue) | |||
|
99 | assert !issue.new_record? | |||
|
100 | issue.reload | |||
|
101 | assert_equal Project.find(2), issue.project | |||
|
102 | assert_equal 'New ticket on a given project', issue.subject | |||
|
103 | assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.') | |||
|
104 | assert_equal User.find_by_login('jsmith'), issue.author | |||
|
105 | ||||
|
106 | assert_equal issue.project.trackers.first, issue.tracker | |||
|
107 | assert_equal 'New', issue.status.name | |||
|
108 | assert_not_equal '2010-01-01', issue.start_date.to_s | |||
|
109 | assert_nil issue.due_date | |||
|
110 | assert_nil issue.assigned_to | |||
|
111 | assert_nil issue.fixed_version | |||
|
112 | assert_nil issue.estimated_hours | |||
|
113 | assert_equal 0, issue.done_ratio | |||
|
114 | end | |||
|
115 | ||||
77 | def test_add_issue_with_default_tracker |
|
116 | def test_add_issue_with_default_tracker | |
78 | # This email contains: 'Project: onlinestore' |
|
117 | # This email contains: 'Project: onlinestore' | |
79 | issue = submit_email( |
|
118 | issue = submit_email( | |
@@ -86,9 +125,9 class MailHandlerTest < ActiveSupport::TestCase | |||||
86 | assert_equal 'Support request', issue.tracker.name |
|
125 | assert_equal 'Support request', issue.tracker.name | |
87 | end |
|
126 | end | |
88 |
|
127 | |||
89 | def test_add_issue_with_status |
|
128 | def test_add_issue_with_status_override | |
90 | # This email contains: 'Project: onlinestore' and 'Status: Resolved' |
|
129 | # This email contains: 'Project: onlinestore' and 'Status: Resolved' | |
91 | issue = submit_email('ticket_on_given_project.eml') |
|
130 | issue = submit_email('ticket_on_given_project.eml', :allow_override => ['status']) | |
92 | assert issue.is_a?(Issue) |
|
131 | assert issue.is_a?(Issue) | |
93 | assert !issue.new_record? |
|
132 | assert !issue.new_record? | |
94 | issue.reload |
|
133 | issue.reload | |
@@ -185,7 +224,7 class MailHandlerTest < ActiveSupport::TestCase | |||||
185 |
|
224 | |||
186 | def test_add_issue_with_custom_fields |
|
225 | def test_add_issue_with_custom_fields | |
187 | issue = submit_email('ticket_with_custom_fields.eml', |
|
226 | issue = submit_email('ticket_with_custom_fields.eml', | |
188 |
:issue => {:project => 'onlinestore'}, :allow_override => ['database', 'Searchable |
|
227 | :issue => {:project => 'onlinestore'}, :allow_override => ['database', 'Searchable_field'] | |
189 | ) |
|
228 | ) | |
190 | assert issue.is_a?(Issue) |
|
229 | assert issue.is_a?(Issue) | |
191 | assert !issue.new_record? |
|
230 | assert !issue.new_record? |
General Comments 0
You need to be logged in to leave comments.
Login now