Show read.html syntax highlighted
% # vim: set syntax=mason:
<%args>
$folder
$uid
$uidv
$sorted_offset
$sortby
$full_headers => 0
$n => 0
</%args>
<& /mail/header.mhtml, title => "Read: " . HTML::Entities::encode($header->{subject}), folder => $folder &>
<table class="message_display">
<tr>
<td>
<div class="controls">
<span class="left">
<% hyperlink('/mail/index.html', "Back to $folder") %>
<%perl>
chomp $header->{date};
chomp $header->{subject};
chomp $header->{from};
if(!$prefs->get('literal', 0)) {
$message = "\n\nOn $header->{date}, $header->{from} wrote:\n";
$message .= wrap('> ','> ',main_body($inline, $attachments));
} else {
$message = "\n\nOn $header->{date}, $header->{from} wrote:\n";
$message .= main_body($inline, $attachments);
$message =~ s!^!> !gm;
}
</%perl>
<form method="post" action="/mail/compose.html">
<input type="submit" name="reply" value="Reply">
<input type="hidden" name="to" value="<% $header->{from} |h %>">
<input type="hidden" name="ref" value="<% "$folder|$uid|$uidv" |h %>">
<input type="hidden" name="subject" value="<% $header->{subject} |h %>">
% if($prefs->get('signature_on_top', 0)) {
<input type="hidden" name="message" value="<% $sigs->getSignature . "\n\n" . $message | h %>">
% } else {
<input type="hidden" name="message" value="<% $message . "\n\n" . $sigs->getSignature | h %>">
% }
</form>
<form method="post" action="/mail/compose.html">
<input type="submit" name="reply" value="Reply To All">
<input type="hidden" name="to" value="<% $header->{from} |h %>">
% my $other_to = $header->{to};
% $other_to =~ s/^[^,]*\Q$reply_address\E[^,]*$//; # Sent to just me
% $other_to =~ s/^[^,]*\Q$reply_address\E[^,]*,\s*//; # Beg of multiple
% $other_to =~ s/,[^,]*\Q$reply_address\E[^,]*$//; # End of multiple
% $other_to =~ s/,[^,]*\Q$reply_address\E[^,]*,\s*/, /; # Middle of multiple
% if($other_to !~ m/^\s*$/) {
<input type="hidden" name="cc" value="<% ($header->{cc} ? "$header->{cc},":"") . $other_to |h %>">
% } elsif($header->{cc}) {
<input type="hidden" name="cc" value="<% $header->{cc} |h %>">
% }
<input type="hidden" name="ref" value="<% "$folder|$uid|$uidv" |h %>">
<input type="hidden" name="subject" value="<% (($header->{subject} =~ m/^re:/i) ? "":"Re: ") . $header->{subject} | h %>">
% if($prefs->get('signature_on_top', 0)) {
<input type="hidden" name="message" value="<% $sigs->getSignature . "\n\n" . $message | h %>">
% } else {
<input type="hidden" name="message" value="<% $message . "\n\n" . $sigs->getSignature | h %>">
% }
</form>
<form method="post" action="/mail/compose.html">
<input type="submit" name="forward" value="Forward">
<input type="hidden" name="ref" value="<% "$folder|$uid|$uidv" |h %>">
<input type="hidden" name="subject" value="<% (($header->{subject} =~ m/^fwd:/i) ? "":"Fwd: ") . $header->{subject} | h %>">
<input type="hidden" name="message" value="<% $sigs->getSignature | h %>">
</form>
<form method="post" action="/mail/process_messages.html">
% if($deleted) {
<input type="submit" name="action" value="Undelete">
% } else {
<input type="submit" name="delete" value="Delete">
% }
<input type="hidden" name="folder" value="<% $folder |h %>">
<input type="hidden" name="start" value="<% $sorted_offset |h %>">
<input type="hidden" name="n" value="<% $n |h %>">
<input type="hidden" name="sortby" value="<% $sortby |h %>">
<input type="hidden" name="uidv" value="<% $uidvalidity |h %>">
<input type="hidden" name="uids" value="<% $uid |h %>">
</form>
</span>
<span class="right">
% if($sorted_offset > 1) {
<a href="<% build_url('/mail/read.html',
{ folder => $folder, start => $sorted_offset, n => $n,
uidv => $uidvalidity, uid => $headers->[0]{uid},
sorted_offset => $sorted_offset-1, sortby => $sortby
}) %>"
% my $tip = $headers->[0]{subject}; $tip =~ s/"//g; $tip =~ s/'/\\'/g;
onmouseover="return escape('<% $tip %>');">
< Previous
</a>
<% $sorted_offset %> of <% $msgcnt %>
% if($headers->[2]{uid} > 0) {
<a href="<% build_url('/mail/read.html',
{ folder => $folder, start => $sorted_offset, n => $n,
uidv => $uidvalidity, uid => $headers->[2]{uid},
sorted_offset => $sorted_offset+1, sortby => $sortby
}) %>"
% my $tip = $headers->[2]{subject}; $tip =~ s/"//g; $tip =~ s/'/\\'/g;
onmouseover="return escape('<% $tip %>');">
Next >
</a>
% }
% } elsif($headers->[1]{uid} > 0) {
1 of <% $msgcnt %>
<a href="<% build_url('/mail/read.html',
{ folder => $folder, start => $sorted_offset, n => $n,
uidv => $uidvalidity, uid => $headers->[1]{uid},
sorted_offset => $sorted_offset+1, sortby => $sortby
}) %>"
% my $tip = $headers->[1]{subject}; $tip =~ s/"//g; $tip =~ s/'/\\'/g;
onmouseover="return escape('<% $tip %>');">
Next >
</a>
% }
</span>
<a class="clearblock"
target="_blank" href="<% build_url('/mail/print.html',
{ sortby => $sortby, sorted_offset => $sorted_offset+1 ,
folder => $folder, uidv => $uidvalidity, uid => $uid,
n => $n }) %>">Printable View</a>
</div>
</td>
</tr>
<tr>
<td class="messageHeader">
<div class="messageHeader">
% if(!$full_headers) {
<b>Subject:</b> <% $header->{subject} |h %>
<br><b>To:</b> <% $header->{to} |h %> <% hyperlink("/mail/addressbook/take.html", "Add to address book...", { addresslist => $header->{to} }) %>
% if(defined($header->{cc}) && $header->{cc} ne "") {
<br><b>Cc:</b> <% $header->{cc} |h %> <% hyperlink("/mail/addressbook/take.html", "Add to address book...", { addresslist => $header->{cc} }) %>
% }
<br><b>From:</b> <% $header->{from} |h %> <% hyperlink("/mail/addressbook/take.html", "Add to address book...", { addresslist => $header->{from} }) %>
<br><b>Date:</b> <% $header->{date} |h %>
<br> <% hyperlink('/mail/read.html',
"view full message header",
{ folder => $folder, start => $sorted_offset, n => $n,
uidv => $uidvalidity, uid => $headers->[1]{uid},
sorted_offset => $sorted_offset, sortby => $sortby,
full_headers => 1 }) %>
% } else {
<pre><% $header->{full_header} |h %>
</pre>
<% hyperlink('/mail/read.html',
"view minimal header",
{ folder => $folder, start => $sorted_offset, n => $n,
uidv => $uidvalidity, uid => $headers->[1]{uid},
sorted_offset => $sorted_offset, sortby => $sortby
}) %>
% }
</div>
</td>
</tr><tr>
<td>
<div class="messageBody">
<%perl>
my $body;
if($prefs->get('linkify')) {
$body = linkify(main_body($inline));
if(!$prefs->get('literal', 0)) {
$body =~ s/$/<br>/mg;
$body = "<br>" . $body;
}
} else {
$body = "<br>" . HTML::Entities::encode(main_body($inline));
if(!$prefs->get('literal', 0)) {
$body =~ s/$/<br>/mg;
}
}
</%perl>
% if($prefs->get('literal', 0)) {
<pre>
% }
<% $body %>
% if($prefs->get('literal', 0)) {
</pre>
% }
</div>
</td>
</tr>
<tr>
<td>
% if(@$attachments) {
<div class="attachments">
% for my $a (@$attachments) {
% $filename = $a->{recommended_filename};
% # FIXME: Further sanitize the filename to alphanumeric with dots/underscore only. Length (first 20 + extension)
% $filename =~ s!^.*/([^/]*)!$1!;
Download: <% hyperlink("/mail/get_attachment.html",
"$filename",
{ type => $a->{type}, subtype => $a->{subtype},
file => $a->{path}, }, "file") %>
<%doc>FIXME: change filename to relative path</%doc>
<br>
<span class="type"><% $a->{type} |h %>/<% $a->{subtype} |h %></span>
<span class="size">(<% $a->{size} %> bytes)</span>
<br>
<% viewer_link($a, $prefs) %>
<br>
<br>
% }
</div>
% }
</td>
</tr>
</table>
<& /mail/footer.mhtml &>
<%init>
my $user = Apache::SiteControl->getCurrentUser($r);
my $prefs = new AlphaMail::Preferences($user->getUsername(),
$user->getAttribute('imap'), $config);
my $sigs = new AlphaMail::Signature($user->getUsername(), $user->getAttribute('imap'), $config);
my $c;
my $error = 0;
my $message;
my $parser = new MIME::Parser;
my $entity;
my $headers;
my $msgcnt;
my $uidvalidity;
my $filename;
my $reply_address = $user->getUsername() . '@' . $user->getAttribute('mx');
if(!$n) {
my @allowed_per_page = $config->getList('allowed_per_page', 20, 35, 50);
$n = $prefs->get('messages_per_page', $allowed_per_page[0]);
}
my $attachments = [];
my $inline = [];
my $header = {};
# Flags
my ($deleted, $replied, $forwarded);
$user->setAttribute($r, 'reading_folder', $folder);
$user->setAttribute($r, 'reading_uid', $uid);
$user->setAttribute($r, 'reading_uidv', $uidv);
$user->setAttribute($r, 'reading_offset', $sorted_offset);
$user->setAttribute($r, 'reading_sortby', $sortby);
my $dir = $config->get("message_tmpdir", '/tmp') . "/" .
$user->getAttribute('imap') . "_" . $user->getUsername();
eval {
if(!-d $dir) {
mkdir $dir or die "Could not create temporary storage for message: $dir.";
}
$c = new AlphaMail::Middleware($user->getAttribute('imap'),
$user->getUsername(),
$user->getAttribute('password'),
$config);
eval {
$message = $c->getMessage($folder, $uid, $uidv);
if($sorted_offset > 1) {
$headers = $c->getMessageHeaders($folder, $sorted_offset-1, 3, $sortby);
$deleted = $headers->[1]{deleted};
$replied = $headers->[1]{answered};
$forwarded = 0;
} else {
$headers = $c->getMessageHeaders($folder, $sorted_offset, 2, $sortby);
$deleted = $headers->[0]{deleted};
$replied = $headers->[0]{answered};
$forwarded = 0;
}
$msgcnt = $headers->[0]{count};
$uidvalidity = $headers->[0]{uidvalidity};
};
if($@) {
$logger->debug("Failed to get message from server: $@");
$error = 1;
}
$parser->output_under($dir);
$parser->decode_headers(0);
$parser->ignore_errors(0);
$entity = $parser->parse_open("<$message");
parse_entity($entity, "", "", $inline, $attachments, $header);
$c->close;
};
if($@) {
$logger->error("Read failed: $@");
$error = $@;
}
$m->redirect('/mail/index.html') if $error;
</%init>
<%once>
use Encode;
use AlphaMail::Preferences;
use Text::Wrap qw(wrap);
use AlphaMail::HTMLHelper qw(url_encode viewer_link hyperlink build_url linkify);
our $logger = Log::Log4perl->get_logger('alphamail');
$Text::Wrap::columns = $config->get('textwrap_columns') || 80;
$Text::Wrap::huge = 'overflow';
sub parse_entity {
my ($entity, $name, $charset, $inline_parts, $attachments, $header) = @_;
defined($name) or $name = "'anonymous'";
my $result = {};
# TODO: Clean this charset crap up
$charset = $result->{charset} =
lc($entity->head->mime_attr('content-type.charset')) || 'us-ascii';
if($entity->head->get('Subject')) {
$header->{subject} = AlphaMail::Middleware::_mimewords_to_utf8(
$entity->head->get('Subject'));
$header->{date} = AlphaMail::Middleware::_mimewords_to_utf8(
$entity->head->get('Date'));
$header->{from} = AlphaMail::Middleware::_mimewords_to_utf8(
$entity->head->get('From'));
$header->{to} = AlphaMail::Middleware::_mimewords_to_utf8(
$entity->head->get('To'));
$header->{cc} = AlphaMail::Middleware::_mimewords_to_utf8(
$entity->head->get('Cc'));
$header->{full_header} = AlphaMail::Middleware::_mimewords_to_utf8(
$entity->head->as_string);
$header->{to} =~ s/[\r\n]//g;
$header->{cc} =~ s/[\r\n]//g;
$header->{to} =~ s!\s{2,}! !g;
$header->{cc} =~ s!\s{2,}! !g;
}
my @parts = $entity->parts;
if (@parts) {
my $i;
foreach $i (0 .. $#parts) {
parse_entity($parts[$i], "", $charset, $inline_parts, $attachments);
}
} else {
$result->{disposition} = $entity->head->mime_attr('content-disposition');
$result->{recommended_filename} = $entity->head->recommended_filename;
($result->{type}, $result->{subtype}) = split('/', $entity->head->mime_type);
$result->{body} = $entity->bodyhandle;
my $path = $result->{body}->path;
my $size = ($path ? (-s $path) : '???');
$result->{path} = $path;
$result->{size} = $size;
if($result->{type} eq 'text' && $result->{subtype} eq 'plain') {
push @$inline_parts, $result;
} elsif($result->{type} eq 'text' && $result->{subtype} eq 'html') {
push @$inline_parts, $result;
$result->{recommended_filename} = 'HTML message' if(length($result->{recommended_filename}) < 1);
push @$attachments, $result;
} else {
push @$attachments, $result;
}
}
}
sub main_body
{
my $inline_parts = shift;
my $attachments = shift;
my $result = '';
my $show_separator = 0;
my $IO;
my $elinks = $config->get('elinks', "/usr/bin/elinks");
return '' if((!defined($inline_parts) || !@$inline_parts) && (!defined($attachments) || !@$attachments));
$show_separator = 1 if($#$inline_parts > 0);
for my $part (@$inline_parts) {
if($part->{subtype} eq 'html') {
$result .= "NOTE: The following part of this message was originally in HTML. The primary text has been sanitized of images and potentially harmful code, but should still be readable. If you want to view the original message you can use the link in the attachment section at the bottom.\n\n";
my @lines = qx($elinks -no-home 1 -dump $part->{path});
for my $l (@lines) {
$l =~ s/^\s*//;
$result .= $l;
}
} else {
my $body = $part->{body};
if ($IO = $body->open("r")) {
while (defined($_ = $IO->getline)) {
eval {
$result .= decode($part->{charset}, $_);
};
if($@) {
$result .= $_;
}
}
}
$IO->close;
}
if($show_separator) {
$result .= "\n\n" . "-" x 72 . "\n";
$show_separator++;
}
}
return $result;
}
</%once>
See more files for this project here