]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
Bug 660691: Allow Bugzilla to parse HTML-only inbound email via email_in.pl
authorMax Kanat-Alexander <mkanat@bugzilla.org>
Tue, 9 Aug 2011 21:04:31 +0000 (14:04 -0700)
committerMax Kanat-Alexander <mkanat@bugzilla.org>
Tue, 9 Aug 2011 21:04:31 +0000 (14:04 -0700)
r=glob, a=mkanat

Bugzilla/Install/Requirements.pm
email_in.pl
template/en/default/global/user-error.html.tmpl

index 071f3ed8f4cba679363688cc973a556d1cd67900..d8119f1b05584ab254fe322ea16c9d2091a09631 100644 (file)
@@ -327,6 +327,13 @@ sub OPTIONAL_MODULES {
         version => 0,
         feature => ['inbound_email'],
     },
+    {
+        package => 'HTML-FormatText-WithLinks',
+        module  => 'HTML::FormatText::WithLinks',
+        # We need 0.13 to set the "bold" marker to "*".
+        version => '0.13',
+        feature => ['inbound_email'],
+    },
 
     # Mail Queueing
     {
index a835c3c9a8bb1f5470975182339e3d6daaaa9207..f16d56175d972c1b54476977a0730da144792dbb 100755 (executable)
@@ -39,6 +39,7 @@ use Email::Address;
 use Email::Reply qw(reply);
 use Email::MIME;
 use Getopt::Long qw(:config bundling);
+use HTML::FormatText::WithLinks;
 use Pod::Usage;
 use Encode;
 use Scalar::Util qw(blessed);
@@ -68,6 +69,7 @@ use constant SIGNATURE_DELIMITER => '-- ';
 use constant BODY_TYPES => qw(
     text/plain
     text/html
+    application/xhtml+xml
     multipart/alternative
 );
 
@@ -321,7 +323,7 @@ sub get_body_and_attachments {
         # Note that this only happens if the email does not contain any
         # text/plain parts. If the email has an empty text/plain part,
         # you're fine, and this message does NOT get thrown.
-        ThrowUserError('email_no_text_plain');
+        ThrowUserError('email_no_body');
     }
 
     debug_print("Picked Body:\n$body", 2);
@@ -343,18 +345,43 @@ sub get_text_alternative {
         }
         debug_print("Alternative Part Content-Type: $ct", 2);
         debug_print("Alternative Part Character Encoding: $charset", 2);
-        if (!$ct || $ct =~ /^text\/plain/i) {
-            $body = $part->body;
-            if (Bugzilla->params->{'utf8'} && !utf8::is_utf8($body)) {
-                $body = Encode::decode($charset, $body);
-            }
-            last;
+        # If we find a text/plain body here, return it immediately.
+        if (!$ct || $ct =~ m{^text/plain}i) {
+            return _decode_body($charset, $part->body);
+        }
+        # If we find a text/html body, decode it, but don't return
+        # it immediately, because there might be a text/plain alternative
+        # later. This could be any HTML type.
+        if ($ct =~ m{^application/xhtml\+xml}i or $ct =~ m{text/html}i) {
+            my $parser = HTML::FormatText::WithLinks->new(
+                # Put footnnote indicators after the text, not before it.
+                before_link => '',
+                after_link  => '[%n]',
+                # Convert bold and italics, use "*" for bold instead of "_".
+                with_emphasis => 1,
+                bold_marker => '*',
+                # If the same link appears multiple times, only create
+                # one footnote.
+                unique_links => 1,
+                # If the link text is the URL, don't create a footnote.
+                skip_linked_urls => 1,
+            );
+            $body = _decode_body($charset, $part->body);
+            $body = $parser->parse($body);
         }
     }
 
     return $body;
 }
 
+sub _decode_body {
+    my ($charset, $body) = @_;
+    if (Bugzilla->params->{'utf8'} && !utf8::is_utf8($body)) {
+        return Encode::decode($charset, $body);
+    }
+    return $body;
+}
+
 sub remove_leading_blank_lines {
     my ($text) = @_;
     $text =~ s/^(\s*\n)+//s;
index a63d42d769a9e81bc6705db3cbeff027268390be..dc0481a67c30648bec4d2d19451316fdffa71ed2 100644 (file)
     [% title = "Email Address Confirmation Failed" %]
     Email address confirmation failed.
 
-  [% ELSIF error == "email_no_text_plain" %]
-    Your message did not contain any text. [% terms.Bugzilla %] does not
-    accept HTML-only email.
+  [% ELSIF error == "email_no_body" %]
+    Your message did not contain any text, as far as we could tell.
 
   [% ELSIF error == "empty_group_description" %]
     [% title = "The group description can not be empty" %]