diff options
author | Eric Wong <normalperson@yhbt.net> | 2014-02-25 03:01:04 +0000 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2014-02-25 03:31:25 +0000 |
commit | 25cc5a69a4a38076ea9e587dfa75165fef2273da (patch) | |
tree | 5a799335ca505f4ec72431e4497b0ab10c7ff872 /lib | |
parent | 858f0a2960123d6d2cbced1bb18e4e5e524df21e (diff) | |
download | public-inbox-25cc5a69a4a38076ea9e587dfa75165fef2273da.tar.gz |
This is to keep content accessible to search engines.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/PublicInbox/View.pm | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/lib/PublicInbox/View.pm b/lib/PublicInbox/View.pm new file mode 100644 index 00000000..125fcd62 --- /dev/null +++ b/lib/PublicInbox/View.pm @@ -0,0 +1,99 @@ +# Copyright (C) 2014, Eric Wong <normalperson@yhbt.net> and all contributors +# License: AGPLv3 or later (https://www.gnu.org/licenses/agpl-3.0.txt) +package PublicInbox::View; +use strict; +use warnings; +use CGI qw/escapeHTML escape/; +use Encode qw/decode encode/; +use Encode::MIME::Header; + +# only one public function: +sub as_html { + my ($class, $mime) = @_; + + headers_to_html_header($mime) . + multipart_text_as_html($mime) . + "</pre>\n"; +} + +# only private functions below. + +sub multipart_text_as_html { + my ($mime) = @_; + my $rv = ""; + my $part_nr = 0; + + # scan through all parts, looking for displayable text + $mime->walk_parts(sub { + my ($part) = @_; + return if $part->subparts; # walk_parts already recurses + + my $part_type = $part->content_type; + if ($part_type =~ m!\btext/[a-z0-9\+\._-]+\b!i) { + my $fn = $part->filename; + + if ($part_nr > 0) { + defined($fn) or $fn = "part #$part_nr"; + $rv .= add_filename_line($fn); + } + + # n.b. $part->body should already be decoded if text + $rv .= escapeHTML($part->body); + $rv .= "\n" unless $rv =~ /\n\z/s; + } else { + $rv .= "-- part #$part_nr "; + $rv .= escapeHTML($part_type); + $rv .= " skipped\n"; + } + ++$part_nr; + }); + $rv; +} + +sub add_filename_line { + my ($fn) = @_; + my $len = 72; + my $pad = "-"; + + $len -= length($fn); + $pad x= ($len/2) if ($len > 0); + "$pad " . escapeHTML($fn) . " $pad\n"; +} + +sub headers_to_html_header { + my ($simple) = @_; + + my $rv = ""; + my @title; + foreach my $h (qw(From To Cc Subject Date)) { + my $v = $simple->header($h); + defined $v or next; + $v = decode("MIME-Header", $v); + $v = encode("utf8", $v); + $v = escapeHTML($v); + $v =~ tr/\n/ /; + $rv .= "$h: $v\n"; + + if ($h eq "From" || $h eq "Subject") { + push @title, $v; + } + } + + foreach my $h (qw(Message-ID In-Reply-To)) { + my $v = $simple->header($h); + defined $v or next; + $v =~ tr/<>//d; + my $html = escapeHTML($v); + my $href = escapeHTML(escape($v)); + $rv .= "$h: <a href=\"$href\">$html</a>\n"; + } + + $rv .= "\n"; + + return ("<html><head><title>". + join(' - ', @title) . + '</title></head><body><pre style="white-space:pre-wrap">' . + $rv); +} + +1; |