#
# Used for displaying the HTML web interface.
# See Documentation/design_www.txt for this.
package PublicInbox::View;
use strict;
use warnings;
-use URI::Escape qw/uri_escape_utf8/;
-use Date::Parse qw/str2time/;
-use Encode qw/find_encoding/;
-use Encode::MIME::Header;
-use Email::MIME::ContentType qw/parse_content_type/;
-use PublicInbox::Hval;
-use PublicInbox::MID qw/mid_clean id_compress mid2path/;
-use Digest::SHA qw/sha1_hex/;
-my $SALT = rand;
-my $MBOX_TITLE = 'title="download thread as gzipped mbox"';
+use PublicInbox::MsgTime qw(msg_datestamp);
+use PublicInbox::Hval qw/ascii_html obfuscate_addrs/;
+use PublicInbox::Linkify;
+use PublicInbox::MID qw/id_compress mid_escape mids references/;
+use PublicInbox::MsgIter;
+use PublicInbox::Address;
+use PublicInbox::WwwStream;
+use PublicInbox::Reply;
require POSIX;
+use Time::Local qw(timegm);
-# TODO: make these constants tunable
-use constant MAX_INLINE_QUOTED => 12; # half an 80x24 terminal
-use constant MAX_TRUNC_LEN => 72;
-use constant T_ANCHOR => '#u';
use constant INDENT => ' ';
+use constant TCHILD => '` ';
+sub th_pfx ($) { $_[0] == 0 ? '' : TCHILD };
-*ascii_html = *PublicInbox::Hval::ascii_html;
+# public functions: (unstable)
-my $enc_utf8 = find_encoding('UTF-8');
-
-# public functions:
sub msg_html {
- my ($ctx, $mime, $full_pfx, $footer) = @_;
- if (defined $footer) {
- $footer = "\n" . $footer;
+ my ($ctx, $mime, $more, $smsg) = @_;
+ my $hdr = $mime->header_obj;
+ my $ibx = $ctx->{-inbox};
+ my $obfs_ibx = $ctx->{-obfs_ibx} = $ibx->{obfuscate} ? $ibx : undef;
+ my $tip = _msg_html_prepare($hdr, $ctx, $more, 0);
+ my $end = 2;
+ PublicInbox::WwwStream->response($ctx, 200, sub {
+ my ($nr, undef) = @_;
+ if ($nr == 1) {
+ # $more cannot be true w/o $smsg being defined:
+ my $upfx = $more ? '../'.mid_escape($smsg->mid).'/' : '';
+ $tip . multipart_text_as_html($mime, $upfx, $obfs_ibx) .
+ '
'
+ } elsif ($more && @$more) {
+ ++$end;
+ msg_html_more($ctx, $more, $nr);
+ } elsif ($nr == $end) {
+ # fake an EOF if generating the footer fails;
+ # we want to at least show the message if something
+ # here crashes:
+ eval {
+ '' . html_footer($hdr, 1, $ctx) .
+ '
' . msg_reply($ctx, $hdr)
+ };
+ } else {
+ undef
+ }
+ });
+}
+
+sub msg_page {
+ my ($ctx) = @_;
+ my $mid = $ctx->{mid};
+ my $ibx = $ctx->{-inbox};
+ my ($first, $more);
+ my $smsg;
+ if (my $srch = $ibx->search) {
+ my ($id, $prev);
+ $smsg = $srch->next_by_mid($mid, \$id, \$prev);
+ $first = $ibx->msg_by_smsg($smsg) if $smsg;
+ if ($first) {
+ my $next = $srch->next_by_mid($mid, \$id, \$prev);
+ $more = [ $id, $prev, $next ] if $next;
+ }
+ return unless $first;
} else {
- $footer = '';
+ $first = $ibx->msg_by_mid($mid) or return;
+ }
+ msg_html($ctx, PublicInbox::MIME->new($first), $more, $smsg);
+}
+
+sub msg_html_more {
+ my ($ctx, $more, $nr) = @_;
+ my $str = eval {
+ my ($id, $prev, $smsg) = @$more;
+ my $mid = $ctx->{mid};
+ $smsg = $ctx->{-inbox}->smsg_mime($smsg);
+ my $next = $ctx->{srch}->next_by_mid($mid, \$id, \$prev);
+ @$more = $next ? ($id, $prev, $next) : ();
+ if ($smsg) {
+ my $mime = $smsg->{mime};
+ my $upfx = '../' . mid_escape($smsg->mid) . '/';
+ _msg_html_prepare($mime->header_obj, $ctx, $more, $nr) .
+ multipart_text_as_html($mime, $upfx,
+ $ctx->{-obfs_ibx}) .
+ '
'
+ } else {
+ '';
+ }
+ };
+ if ($@) {
+ warn "Error lookup up additional messages: $@\n";
+ $str = 'Error looking up additional messages
';
}
- headers_to_html_header($mime, $full_pfx, $ctx) .
- multipart_text_as_html($mime, $full_pfx) .
- '
' .
- html_footer($mime, 1, $full_pfx, $ctx) .
- $footer .
- '