package JWebmail::View::RenderMail; use Mojo::Base -base; use Mojo::ByteStream; use Mojo::Util 'xml_escape'; has 'c'; sub render_text_plain { my ($_self, $_subtype, $content, $_path) = @_; $content = xml_escape $content; return qq'
$content
\n'; } sub render_text_html { my ($self, $_subtype, $_content, $path) = @_; my $url = $self->c->url_for('raw', id => $self->c->stash('id')); $url = $url->query(path => join('.', @$path)) if @$path; return qq'\n'; } sub render_image { my ($_self, $subtype, $content, $_path) = @_; return qq''; } sub render_multipart_alternative { my ($self, $_subtype, $content, $path) = @_; my $parts = $content->{parts}; my $R = qq'
'; my $i = 0; my $end; for (reverse @$parts) { if (!$end) { my $x = $self->mime_render(to_mime_types($_->{head}), $_->{body}, [@$path, $#$parts-$i]); if ($x) { $R .= $x; $end = 1; } } else { $R .= '
'; $R .= ''; $R .= to_mime_type($_->{head}); $R .= "\n"; $R .= $self->mime_render(to_mime_types($_->{head}), $_->{body}, [@$path, $#$parts-$i]); $R .= "
\n"; } ++$i; } return $R . "
\n"; } sub render_multipart { my ($self, $_subtype, $content, $path) = @_; my $parts = $content->{parts}; my $R = qq'
'; my $i = 0; for (@$parts) { if ( !$_->{head}{content_disposition} || lc $_->{head}{content_disposition} eq 'none' || lc $_->{head}{content_disposition} eq 'inline') { $R .= $self->mime_render(to_mime_types($_->{head}), $_->{body}, [@$path, $i]); } elsif (lc $_->{head}{content_disposition} eq 'attachment') { $R .= '

'; $R .= $self->c->link_to($self->c->url_for(raw => id => $self->c->stash('id'))->query(path => join('.', @$path, $i)), (download => $_->{head}{filename}) => sub { 'Attachment ' . xml_escape($_->{head}{filename}) . ' of type ' . to_mime_type($_->{head}); }); $R .= "

\n"; } else { warn "unknown Content-Disposition '$_->{head}{content_disposition}'"; $R .= "

unknown Content-Disposition '$_->{head}{content_disposition}'

\n"; } ++$i; } return $R . "
\n"; } sub _format_header { my ($self, $category, $value) = @_; my $R = ''; if (ref $value eq 'ARRAY' && $value->@*) { $R .= '
' . xml_escape(uc $self->c->l($category)) . "
\n"; for ($value->@*) { $R .= '
'; $R .= xml_escape($_->{display_name} ? qq("$_->{display_name}" <$_->{address}>) : "$_->{address}"); $R .= "
\n"; } } return $R; } sub render_message { my ($self, $subtype, $msg, $path) = @_; warn "unkown mime-subtype $subtype" unless $subtype eq 'rfc822'; my $R .= '
'; $R .= '
'; $R .= '
' . xml_escape(uc $self->c->l('subject')) . '
'; $R .= '
' . xml_escape($msg->{head}{subject}) . "
\n"; $R .= $self->_format_header(from => $msg->{head}{from}); $R .= $self->_format_header(to => $msg->{head}{to}); $R .= $self->_format_header(cc => $msg->{head}{cc}); $R .= $self->_format_header(bcc => $msg->{head}{bcc}); $R .= '
' . xml_escape(uc $self->c->l('date')) . '
'; $R .= '
' . xml_escape($msg->{head}{date}) . "
\n"; $R .= '
' . xml_escape(uc $self->c->l('content-type')) . '
'; $R .= '
' . to_mime_type($msg->{head}{mime}) . "
\n"; $R .= "
\n"; #my $content = ref $msg->{body} && exists $msg->{body}{parts} ? $msg->{body}{parts} : $msg->{body}; $R .= $self->mime_render(to_mime_types($msg->{head}{mime}), $msg->{body}, [@$path, 0]); return $R . "
\n"; } our %MIME_Render_Subs = ( 'text/plain' => \&render_text_plain, 'text/html' => \&render_text_html, 'multipart/alternative' => \&render_multipart_alternative, 'multipart' => \&render_multipart, 'message' => \&render_message, 'image' => \&render_image, ); sub mime_render { my ($self, $maintype, $subtype, $content, $path) = @_; my $renderer = $MIME_Render_Subs{"$maintype/$subtype"} || $MIME_Render_Subs{$maintype}; unless ($renderer) { return "

Unsupported MIME type of $maintype/$subtype.

\n"; } return $renderer->($self, $subtype, $content, $path); } sub to_mime_type { lc xml_escape("$_[0]->{content_maintype}/$_[0]->{content_subtype}") } sub to_mime_types { return xml_escape($_[0]->{content_maintype}), xml_escape($_[0]->{content_subtype}) } sub format_mail { my ($self, $mail) = @_; return Mojo::ByteStream->new($self->mime_render('message', 'rfc822', $mail, [])); } 1 __END__ =encoding utf-8 =head1 NAME JWebmail::View::RenderMail - Does the heavy lifting of converting an E-Mail to HTML =head1 FUNCTIONS =head2 to_mime_type Combines the content_maintype and content_subtype attributes into the regular MIME description. These attributes are found in a mail head mime section or as head for multipart messages. =head1 METHODS =head2 format_mail Renders a mail to html recursively.