diff options
-rw-r--r-- | Documentation/design_www.txt | 1 | ||||
-rw-r--r-- | lib/PublicInbox/View.pm | 65 | ||||
-rw-r--r-- | lib/PublicInbox/WWW.pm | 18 |
3 files changed, 75 insertions, 9 deletions
diff --git a/Documentation/design_www.txt b/Documentation/design_www.txt index 39b12414..1be4d18e 100644 --- a/Documentation/design_www.txt +++ b/Documentation/design_www.txt @@ -15,6 +15,7 @@ URL naming /$LISTNAME/$MESSAGE_ID -> 301 to /$LISTNAME/$MESSAGE_ID /$LISTNAME/$MESSAGE_ID/raw -> raw mbox /$LISTNAME/$MESSAGE_ID/f/ -> HTML content (full quotes) +/$LISTNAME/$MESSAGE_ID/R/ -> HTML reply instructions ### Legacy endpoints (may be ambiguous given Message-IDs with similar suffixes) /$LISTNAME/m/$MESSAGE_ID/ -> 301 to /$LISTNAME/$MESSAGE_ID/ diff --git a/lib/PublicInbox/View.pm b/lib/PublicInbox/View.pm index c28be66d..6b81678a 100644 --- a/lib/PublicInbox/View.pm +++ b/lib/PublicInbox/View.pm @@ -44,6 +44,45 @@ sub msg_html { '</pre></body></html>'; } +# /$LISTNAME/$MESSAGE_ID/R/ +sub msg_reply { + my ($ctx, $hdr, $footer) = @_; + my $s = $hdr->header('Subject'); + $s = '(no subject)' if (!defined $s) || ($s eq ''); + my $f = $hdr->header('From'); + $f = '' unless defined $f; + $s = PublicInbox::Hval->new_oneline($s); + my $mid = $hdr->header('Message-ID'); + $mid = PublicInbox::Hval->new_msgid($mid); + my $t = $s->as_html; + my $se_url = + 'https://kernel.org/pub/software/scm/git/docs/git-send-email.html'; + + my ($arg, $link) = mailto_arg_link($hdr); + push @$arg, '/path/to/YOUR_REPLY'; + + "<html><head><title>replying to \"$t\"</title></head><body><pre>" . + "replying to message:\n\n" . + "Subject: <b>$t</b>\n" . + "From: ". ascii_html($f) . + "\nDate: " . ascii_html($hdr->header('Date')) . + "\nMessage-ID: <" . $mid->as_html . ">\n\n" . + "There are multiple ways to reply:\n\n" . + "* Save the following mbox file, import it into your mail client,\n" . + " and reply-to-all from there: <a\nhref=../raw>mbox</a>\n\n" . + "* Reply to all the recipients using the <b>--to</b>, <b>--cc</b>,\n" . + " and <b>--in-reply-to</b> switches of git-send-email(1):\n\n" . + "\tgit send-email \\\n\t\t" . + join(" \\ \n\t\t", @$arg ). "\n\n" . + qq( <a\nhref="$se_url">$se_url</a>\n\n) . + "* If your mail client supports setting the <b>In-Reply-To</b>" . + " header\n via mailto: links, try the " . + qq(<a\nhref="$link">mailto: link</a>\n) . + "\nFor context, the original <a\nhref=../>message</a> or " . + qq(<a\nhref="../t/#u">thread</a>) . + '</pre><hr /><pre>' . $footer . '</pre></body></html>'; +} + sub feed_entry { my ($class, $mime, $full_pfx) = @_; @@ -131,7 +170,7 @@ sub index_entry { my $txt = "${path}$href/raw"; $rv = "\n<a\nhref=\"$mhref\">$more</a> <a\nhref=\"$txt\">raw</a> "; - $rv .= html_footer($hdr, 0, undef, $ctx); + $rv .= html_footer($hdr, 0, undef, $ctx, $mhref); if (defined $irt) { unless (defined $parent_anchor) { @@ -537,8 +576,8 @@ sub _parent_headers_nosrch { $rv; } -sub html_footer { - my ($hdr, $standalone, $full_pfx, $ctx) = @_; +sub mailto_arg_link { + my ($hdr) = @_; my %cc; # everyone else my $to; # this is the From address @@ -553,24 +592,35 @@ sub html_footer { $to ||= $dst; } } - Email::Address->purge_cache if $standalone; + Email::Address->purge_cache; + my @arg; my $subj = $hdr->header('Subject') || ''; $subj = "Re: $subj" unless $subj =~ /\bRe:/i; my $mid = $hdr->header('Message-ID'); + push @arg, "--in-reply-to='" . ascii_html($mid) . "'"; my $irt = uri_escape_utf8($mid); delete $cc{$to}; + push @arg, '--to=' . ascii_html($to); $to = uri_escape_utf8($to); $subj = uri_escape_utf8($subj); - - my $cc = uri_escape_utf8(join(',', sort values %cc)); + my $cc = join(',', sort values %cc); + push @arg, '--cc=' . ascii_html($cc); + $cc = uri_escape_utf8($cc); my $href = "mailto:$to?In-Reply-To=$irt&Cc=${cc}&Subject=$subj"; $href =~ s/%20/+/g; + (\@arg, $href); +} + +sub html_footer { + my ($mime, $standalone, $full_pfx, $ctx, $mhref) = @_; + my $srch = $ctx->{srch} if $ctx; my $upfx = $full_pfx ? '../' : '../../'; my $tpfx = $full_pfx ? '' : '../'; my $idx = $standalone ? " <a\nhref=\"$upfx\">index</a>" : ''; + my $irt = ''; if ($srch && $standalone) { $idx .= qq{ / follow: <a\nhref="${tpfx}t.atom">Atom feed</a>\n}; @@ -599,7 +649,8 @@ sub html_footer { $irt = ''; } - "$irt<a\nhref=\"" . ascii_html($href) . '">reply</a>' . $idx; + $mhref = './' unless defined $mhref; + $irt . qq(<a\nhref="${mhref}R/">reply</a>) . $idx; } sub linkify_ref_nosrch { diff --git a/lib/PublicInbox/WWW.pm b/lib/PublicInbox/WWW.pm index 77910f67..1f28df20 100644 --- a/lib/PublicInbox/WWW.pm +++ b/lib/PublicInbox/WWW.pm @@ -21,7 +21,7 @@ require PublicInbox::Git; use PublicInbox::GitHTTPBackend; our $LISTNAME_RE = qr!\A/([\w\.\-]+)!; our $MID_RE = qr!([^/]+)!; -our $END_RE = qr!(f/|T/|t/|t\.mbox(?:\.gz)?|t\.atom|raw|)!; +our $END_RE = qr!(f/|T/|t/|R/|t\.mbox(?:\.gz)?|t\.atom|raw|)!; our $pi_config; sub run { @@ -58,7 +58,7 @@ sub run { msg_page($ctx, $1, $2, $3); # in case people leave off the trailing slash: - } elsif ($path_info =~ m!$LISTNAME_RE/$MID_RE/(f|T|t)\z!o) { + } elsif ($path_info =~ m!$LISTNAME_RE/$MID_RE/(f|T|t|R)\z!o) { my ($listname, $mid, $suffix) = ($1, $2, $3); $suffix .= $suffix =~ /\A[tT]\z/ ? '/#u' : '/'; r301($ctx, $listname, $mid, $suffix); @@ -200,6 +200,19 @@ sub get_full_html { [ PublicInbox::View::msg_html($ctx, $mime, undef, $foot)] ]; } +# /$LISTNAME/$MESSAGE_ID/R/ -> HTML content (fullquotes) +sub get_reply_html { + my ($ctx) = @_; + my $x = mid2blob($ctx) or return r404($ctx); + + require PublicInbox::View; + my $foot = footer($ctx); + require Email::MIME; + my $hdr = Email::MIME->new($x)->header_obj; + [ 200, [ 'Content-Type' => 'text/html; charset=UTF-8' ], + [ PublicInbox::View::msg_reply($ctx, $hdr, $foot)] ]; +} + # /$LISTNAME/$MESSAGE_ID/t/ sub get_thread { my ($ctx, $flat) = @_; @@ -407,6 +420,7 @@ sub msg_page { 'T/' eq $e and return get_thread($ctx, 1); 'raw' eq $e and return get_mid_txt($ctx); 'f/' eq $e and return get_full_html($ctx); + 'R/' eq $e and return get_reply_html($ctx); } r404($ctx); } |