diff --git a/app/models/mail_handler.rb b/app/models/mail_handler.rb index be4b363b1..7f50f3771 100755 --- a/app/models/mail_handler.rb +++ b/app/models/mail_handler.rb @@ -447,16 +447,23 @@ class MailHandler < ActionMailer::Base end end - # Returns the text/plain part of the email - # If not found (eg. HTML-only email), returns the body with tags removed + # Returns text content of the email. If the value of + # mail_handler_preferred_body_part in configuration.yml is 'html' and the + # email has text/html part, it returns Textile or Markdown converted from + # text/html part. Otherwise, it returns text/plain part. def plain_text_body return @plain_text_body unless @plain_text_body.nil? - # check if we have any plain-text parts with content - @plain_text_body = email_parts_to_text(email.all_parts.select {|p| p.mime_type == 'text/plain'}).presence - - # if not, we try to parse the body from the HTML-parts - @plain_text_body ||= email_parts_to_text(email.all_parts.select {|p| p.mime_type == 'text/html'}).presence + multipart_parse_order = + if Redmine::Configuration['mail_handler_preferred_body_part'].to_s.casecmp('html') == 0 + ['text/html', 'text/plain'] + else + ['text/plain', 'text/html'] + end + multipart_parse_order.each do |mime_type| + @plain_text_body ||= email_parts_to_text(email.all_parts.select {|p| p.mime_type == mime_type}).presence + return @plain_text_body unless @plain_text_body.nil? + end # If there is still no body found, and there are no mime-parts defined, # we use the whole raw mail body diff --git a/config/configuration.yml.example b/config/configuration.yml.example index bff4c9740..2ba58a2f6 100644 --- a/config/configuration.yml.example +++ b/config/configuration.yml.example @@ -83,6 +83,16 @@ default: autologin_cookie_path: autologin_cookie_secure: + # Configuration of email receiving. + # + # Configures which type of part in a multipart email should be parsed first + # when receiving emails if the email has both text/plain and text/html part. + # Possible values are 'plain' (default) and 'html'. + # Examples: + # mail_handler_preferred_body_part: html + # mail_handler_preferred_body_part: plain + mail_handler_preferred_body_part: + # Configuration of SCM executable command. # # Absolute path (e.g. /usr/local/bin/hg) or command name (e.g. hg.exe, bzr.exe) diff --git a/test/unit/mail_handler_test.rb b/test/unit/mail_handler_test.rb index 9d7fd6d12..5614bda6f 100644 --- a/test/unit/mail_handler_test.rb +++ b/test/unit/mail_handler_test.rb @@ -662,6 +662,16 @@ class MailHandlerTest < ActiveSupport::TestCase assert_equal '', issue.description end + def test_preferred_body_part_configuration + Redmine::Configuration.stubs(:[]).with('mail_handler_preferred_body_part').returns('plain') + issue = submit_email('text_and_html_part.eml', :issue => {:project => 'ecookbook'}) + assert_equal 'The text part.', issue.description + + Redmine::Configuration.stubs(:[]).with('mail_handler_preferred_body_part').returns('html') + issue = submit_email('text_and_html_part.eml', :issue => {:project => 'ecookbook'}) + assert_equal 'The html part.', issue.description + end + def test_attachment_text_part_should_be_added_as_issue_attachment issue = submit_email('multiple_text_parts.eml', :issue => {:project => 'ecookbook'}) assert_not_include 'Plain text attachment', issue.description