Project

General

Profile

Patch #4409 ยป 0001-Remove-the-body-of-incoming-emails-after-specific-de.patch

Eric Davis, 2009-12-16 00:20

View differences:

app/models/mail_handler.rb
81 81
  MESSAGE_ID_RE = %r{^<redmine\.([a-z0-9_]+)\-(\d+)\.\d+@}
82 82
  ISSUE_REPLY_SUBJECT_RE = %r{\[[^\]]*#(\d+)\]}
83 83
  MESSAGE_REPLY_SUBJECT_RE = %r{\[[^\]]*msg(\d+)\]}
84
  
84

  
85 85
  def dispatch
86 86
    headers = [email.in_reply_to, email.references].flatten.compact
87 87
    if headers.detect {|h| h.to_s =~ MESSAGE_ID_RE}
......
131 131
    if issue.subject.blank?
132 132
      issue.subject = '(no subject)'
133 133
    end
134
    issue.description = plain_text_body
135 134
    # custom fields
136 135
    issue.custom_field_values = issue.available_custom_fields.inject({}) do |h, c|
137 136
      if value = get_keyword(c.name, :override => true)
......
139 138
      end
140 139
      h
141 140
    end
141
    issue.description = cleanup_body(plain_text_body)
142 142
    # add To and Cc as watchers before saving so the watchers can reply to Redmine
143 143
    add_watchers(issue)
144 144
    issue.save!
......
167 167
    raise UnauthorizedAction unless status.nil? || user.allowed_to?(:edit_issues, issue.project)
168 168

  
169 169
    # add the note
170
    journal = issue.init_journal(user, plain_text_body)
170
    journal = issue.init_journal(user, cleanup_body(plain_text_body))
171 171
    add_attachments(issue)
172 172
    # check workflow
173 173
    if status && issue.new_statuses_allowed_to(user).include?(status)
......
242 242
      end
243 243
    end
244 244
  end
245
  
245

  
246 246
  # Returns the text/plain part of the email
247 247
  # If not found (eg. HTML-only email), returns the body with tags removed
248 248
  def plain_text_body
......
287 287
      user.save ? user : nil
288 288
    end
289 289
  end
290

  
291
  private
292
  
293
  # Removes the email body of text after the truncation configurations.
294
  def cleanup_body(body)
295
    if Setting.emails_truncate.present?
296
      truncate_tokens = Setting.emails_truncate.split("\n")
297

  
298
      truncate_tokens.each do |token|
299
        next if token.blank?
300
        
301
        regex = Regexp.new(token + '.*', Regexp::IGNORECASE | Regexp::MULTILINE)
302
        body.gsub!(regex, '')
303
      end
304
    end
305
    
306
    return body.chomp
307
  end
290 308
end
app/views/settings/_mail_handler.rhtml
1 1
<% form_tag({:action => 'edit', :tab => 'mail_handler'}) do %>
2 2

  
3 3
<div class="box tabular settings">
4
  <p>
5
    <label><%= l(:setting_emails_truncate) %></label>
6
    <%= text_area_tag 'settings[emails_truncate]', Setting.emails_truncate, :rows => 5, :cols => 80 %>
7
    <br /><em><%= l(:text_line_separated) %></em>
8
  </p>
9
</div>
10

  
11
<div class="box tabular settings">
4 12
<p><label><%= l(:setting_mail_handler_api_enabled) %></label>
5 13
<%= hidden_field_tag 'settings[mail_handler_api_enabled]', 0 %>
6 14
<%= check_box_tag 'settings[mail_handler_api_enabled]', 1, Setting.mail_handler_api_enabled?,
......
16 24
</div>
17 25

  
18 26
<%= submit_tag l(:button_save) %>
27

  
19 28
<% end %>
config/locales/en.yml
323 323
  setting_issue_done_ratio_issue_field: Use the issue field
324 324
  setting_issue_done_ratio_issue_status: Use the issue status
325 325
  setting_start_of_week: Start calendars on
326
  setting_emails_truncate: "Truncate emails after the following strings"
326 327
  
327 328
  permission_add_project: Create project
328 329
  permission_edit_project: Edit project
......
801 802
  text_tracker_no_workflow: No workflow defined for this tracker
802 803
  text_unallowed_characters: Unallowed characters
803 804
  text_comma_separated: Multiple values allowed (comma separated).
805
  text_line_separated: Multiple values allowed (line separated).
804 806
  text_issues_ref_in_commit_messages: Referencing and fixing issues in commit messages
805 807
  text_issue_added: "Issue {{id}} has been reported by {{author}}."
806 808
  text_issue_updated: "Issue {{id}} has been updated by {{author}}."
config/settings.yml
174 174
  default: ''
175 175
start_of_week:
176 176
  default: ''
177
emails_truncate:
178
  default: ''
test/fixtures/mail_handler/ticket_on_given_project.eml
30 30
malesuada fames ac turpis egestas. Quisque sit amet libero. In hac habitasse 
31 31
platea dictumst.
32 32

  
33
---
34

  
35
This paragraph is after the delimiter so it shouldn't appear.
36

  
33 37
Nulla et nunc. Duis pede. Donec et ipsum. Nam ut dui tincidunt neque 
34 38
sollicitudin iaculis. Duis vitae dolor. Vestibulum eget massa. Sed lorem. 
35 39
Nullam volutpat cursus erat. Cras felis dolor, lacinia quis, rutrum et, 
test/fixtures/mail_handler/ticket_reply.eml
25 25
Content-Transfer-Encoding: quoted-printable
26 26

  
27 27
This is reply
28

  
29
---
30

  
31
This is my sig.
32

  
28 33
------=_NextPart_000_0067_01C8D3CE.711F9CC0
29 34
Content-Type: text/html;
30 35
	charset="utf-8"
test/unit/mail_handler_test.rb
204 204
    assert issue.is_a?(Issue)
205 205
    assert_equal 1, ActionMailer::Base.deliveries.size
206 206
  end
207

  
208
  context "truncate emails based on the Setting" do
209
    context "with no setting" do
210
      setup do
211
        Setting.emails_truncate = ''
212
      end
213

  
214
      should "add the entire email into the issue" do
215
        issue = submit_email('ticket_on_given_project.eml')
216

  
217
        assert_issue_created(issue)
218
        assert issue.description.include?('---')
219
        assert issue.description.include?('This paragraph is after the delimiter')
220
      end
221
    end
222

  
223
    context "with a single string" do
224
      setup do
225
        Setting.emails_truncate = '---'
226
      end
227

  
228
      should "truncate the email at the delimiter for the issue" do
229
        issue = submit_email('ticket_on_given_project.eml')
230

  
231
        assert_issue_created(issue)
232
        assert !issue.description.include?('---')
233
        assert !issue.description.include?('This paragraph is after the delimiter')
234
        assert issue.description.include?('platea dictumst.')
235
      end
236

  
237
    end
238

  
239
    context "with multiple strings" do
240
      setup do
241
        Setting.emails_truncate = "---\nBREAK\nid"
242
      end
243

  
244
      should "truncate the email at the first delimiter found (id)" do
245
        issue = submit_email('ticket_on_given_project.eml')
246

  
247
        assert_issue_created(issue)
248
        assert !issue.description.include?('---')
249
        assert !issue.description.include?('This paragraph is after the delimiter')
250
        assert !issue.description.include?('platea dictumst.')
251
        assert issue.description.include?('blandit eleifend augue. Nulla facilisi. Duis ')
252
      end
253

  
254
    end
255

  
256
    
257
  end
207 258
  
259
  def test_add_issue_with_strip_delimiter_should_not_have_text_after_delimiter
260
    with_settings :emails_truncate => '---' do
261
      # This email contains: 'Project: onlinestore'
262
      issue = submit_email('ticket_on_given_project.eml')
263
      assert issue.is_a?(Issue)
264
      assert !issue.new_record?
265
      issue.reload
266
      assert_equal 'New ticket on a given project', issue.subject
267
      assert !issue.description.include?("This paragraph is after the delimiter so it shouldn't appear."), "Delimited text was not stripped"
268
      assert !issue.description.include?("---"), "Delimiter was not stripped"
269
    end
270
  end
271

  
272
  def test_add_issue_with_strip_delimiter_should_not_have_delimiter
273
    with_settings :emails_truncate => '---' do
274
      # This email contains: 'Project: onlinestore'
275
      issue = submit_email('ticket_on_given_project.eml')
276
      assert issue.is_a?(Issue)
277
      assert !issue.new_record?
278
      issue.reload
279
      assert_equal 'New ticket on a given project', issue.subject
280
      assert !issue.description.include?("---"), "Delimiter was not stripped"
281
    end
282
  end
283

  
208 284
  def test_add_issue_note
209 285
    journal = submit_email('ticket_reply.eml')
210 286
    assert journal.is_a?(Journal)
......
259 335
    assert_equal 'This is a html-only email.', issue.description
260 336
  end
261 337

  
338
  def test_add_issue_note_with_strip_delimiter_should_not_have_text_after_delimiter
339
    with_settings :emails_truncate => '---' do
340
      journal = submit_email('ticket_reply.eml')
341
      assert journal.is_a?(Journal)
342
      assert !journal.notes.include?("This is my sig"), "Delimited text was not stripped"
343
    end
344
  end
345
  
346
  def test_add_issue_note_with_strip_delimiter_should_not_have_delimiter
347
    with_settings :emails_truncate => '---' do
348
      journal = submit_email('ticket_reply.eml')
349
      assert journal.is_a?(Journal)
350
      assert !journal.notes.include?("---"), "Delimiter was not stripped"
351
    end
352
  end
353
  
262 354
  private
263 355
  
264 356
  def submit_email(filename, options={})
265 357
    raw = IO.read(File.join(FIXTURES_PATH, filename))
266 358
    MailHandler.receive(raw, options)
267 359
  end
360

  
361
  def assert_issue_created(issue)
362
    assert issue.is_a?(Issue)
363
    assert !issue.new_record?
364
    issue.reload
365
  end
268 366
end
    (1-1/1)