* [PATCH 01/11] feed: remove threading from index
@ 2015-08-20 2:57 Eric Wong
2015-08-20 2:57 ` [PATCH 02/11] feed: move timestamp parsing to view Eric Wong
` (9 more replies)
0 siblings, 10 replies; 11+ messages in thread
From: Eric Wong @ 2015-08-20 2:57 UTC (permalink / raw)
To: meta
We'll be making the index smarter for people with search
support enabled. Otherwise, it'll be chronological and
a bit dumb. At least it'll use less memory.
---
lib/PublicInbox/Feed.pm | 72 ++++++++++++++++---------------------------------
1 file changed, 23 insertions(+), 49 deletions(-)
diff --git a/lib/PublicInbox/Feed.pm b/lib/PublicInbox/Feed.pm
index 95bde4f..253eed2 100644
--- a/lib/PublicInbox/Feed.pm
+++ b/lib/PublicInbox/Feed.pm
@@ -40,7 +40,7 @@ sub generate {
my $git = PublicInbox::GitCatFile->new($ctx->{git_dir});
each_recent_blob($ctx, sub {
- my ($add) = @_;
+ my ($add, undef) = @_;
add_to_feed($feed_opts, $feed, $add, $git);
});
$git = undef; # destroy pipes
@@ -50,7 +50,6 @@ sub generate {
sub generate_html_index {
my ($class, $ctx) = @_;
- require PublicInbox::Thread;
my $max = $ctx->{max} || MAX_PER_PAGE;
my $feed_opts = get_feedopts($ctx);
@@ -58,30 +57,27 @@ sub generate_html_index {
my $title = $feed_opts->{description} || '';
$title = PublicInbox::Hval->new_oneline($title)->as_html;
- my @messages;
- my $git_dir = $ctx->{git_dir};
- my $git = PublicInbox::GitCatFile->new($git_dir);
- my ($first, $last) = each_recent_blob($ctx, sub {
- mime_load_for_sort($git, $_[0], \@messages);
- });
- $git = undef; # destroy pipes.
-
- my $th = PublicInbox::Thread->new(@messages);
- $th->thread;
my $html = "<html><head><title>$title</title>" .
'<link rel="alternate" title="Atom feed"' . "\nhref=\"" .
$feed_opts->{atomurl} . "\"\ntype=\"application/atom+xml\"/>" .
'</head><body>' . PRE_WRAP;
- # sort child messages in chronological order
- $th->order(*PublicInbox::Thread::sort_ts);
-
- # except we sort top-level messages reverse chronologically
- my $state = [ $ctx->{srch}, {}, $first, 0 ];
- for (PublicInbox::Thread::rsort_ts($th->rootset)) {
- dump_msg($_, 0, \$html, $state)
- }
+ my $state;
+ my $git = PublicInbox::GitCatFile->new($ctx->{git_dir});
+ my (undef, $last) = each_recent_blob($ctx, sub {
+ my ($path, $commit) = @_;
+ unless (defined $state) {
+ $state = [ $ctx->{srch}, {}, $commit, 0 ];
+ }
+ my $mime = do_cat_mail($git, $_[0]) or return 0;
+ my $t = eval { str2time($mime->header('Date')) };
+ defined($t) or $t = 0;
+ $mime->header_set('X-PI-TS', $t);
+ $html .= PublicInbox::View->index_entry($mime, 0, $state);
+ 1;
+ });
Email::Address->purge_cache;
+ $git = undef; # destroy pipes.
my $footer = nav_footer($ctx->{cgi}, $last, $feed_opts, $state);
if ($footer) {
@@ -144,12 +140,12 @@ sub each_recent_blob {
my %deleted; # only an optimization at this point
my $last;
my $nr = 0;
- my @commits = ();
+ my ($cur_commit, $first_commit, $last_commit);
while (my $line = <$log>) {
if ($line =~ /$addmsg/o) {
my $add = $1;
- next if $deleted{$add};
- $nr += $cb->($add);
+ next if $deleted{$add}; # optimization-only
+ $nr += $cb->($add, $cur_commit);
if ($nr >= $max) {
$last = 1;
last;
@@ -157,24 +153,23 @@ sub each_recent_blob {
} elsif ($line =~ /$delmsg/o) {
$deleted{$1} = 1;
} elsif ($line =~ /^commit (${hex}{7,40})/o) {
- push @commits, $1;
+ $cur_commit = $1;
+ $first_commit = $1 unless defined $first_commit;
}
}
if ($last) {
while (my $line = <$log>) {
if ($line =~ /^commit (${hex}{7,40})/o) {
- push @commits, $1;
+ $last_commit = $1;
last;
}
}
- } else {
- push @commits, undef;
}
close $log; # we may EPIPE here
# for pagination
- ($commits[0], $commits[-1]);
+ ($first_commit, $last_commit);
}
# private functions below
@@ -279,16 +274,6 @@ sub add_to_feed {
1;
}
-sub dump_msg {
- my ($self, $level, $html, $state) = @_;
- my $mime = $self->message;
- if ($mime) {
- $$html .= PublicInbox::View->index_entry($mime, $level, $state);
- }
- dump_msg($self->child, $level+1, $html, $state) if $self->child;
- dump_msg($self->next, $level, $html, $state) if $self->next;
-}
-
sub do_cat_mail {
my ($git, $path) = @_;
my $mime = eval {
@@ -298,15 +283,4 @@ sub do_cat_mail {
$@ ? undef : $mime;
}
-sub mime_load_for_sort {
- my ($git, $path, $messages) = @_;
- my $mime = do_cat_mail($git, $path) or return 0;
-
- my $t = eval { str2time($mime->header('Date')) };
- defined($t) or $t = 0;
- $mime->header_set('X-PI-TS', $t);
- push @$messages, $mime;
- 1;
-}
-
1;
--
EW
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 02/11] feed: move timestamp parsing to view
2015-08-20 2:57 [PATCH 01/11] feed: remove threading from index Eric Wong
@ 2015-08-20 2:57 ` Eric Wong
2015-08-20 2:57 ` [PATCH 03/11] use tables for rendering comment nesting Eric Wong
` (8 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Eric Wong @ 2015-08-20 2:57 UTC (permalink / raw)
To: meta
We don't need share duplicate logic across both files.
---
lib/PublicInbox/Feed.pm | 5 +----
lib/PublicInbox/View.pm | 17 ++++++++++++-----
2 files changed, 13 insertions(+), 9 deletions(-)
diff --git a/lib/PublicInbox/Feed.pm b/lib/PublicInbox/Feed.pm
index 253eed2..0b7ef7f 100644
--- a/lib/PublicInbox/Feed.pm
+++ b/lib/PublicInbox/Feed.pm
@@ -5,7 +5,7 @@ use strict;
use warnings;
use Email::Address;
use Email::MIME;
-use Date::Parse qw(strptime str2time);
+use Date::Parse qw(strptime);
use PublicInbox::Hval;
use PublicInbox::GitCatFile;
use PublicInbox::View;
@@ -70,9 +70,6 @@ sub generate_html_index {
$state = [ $ctx->{srch}, {}, $commit, 0 ];
}
my $mime = do_cat_mail($git, $_[0]) or return 0;
- my $t = eval { str2time($mime->header('Date')) };
- defined($t) or $t = 0;
- $mime->header_set('X-PI-TS', $t);
$html .= PublicInbox::View->index_entry($mime, 0, $state);
1;
});
diff --git a/lib/PublicInbox/View.pm b/lib/PublicInbox/View.pm
index b3545a4..4a8e54a 100644
--- a/lib/PublicInbox/View.pm
+++ b/lib/PublicInbox/View.pm
@@ -97,11 +97,14 @@ sub index_entry {
}
my $ts = $mime->header('X-PI-TS');
- my $fmt = '%Y-%m-%d %H:%M UTC';
+ unless (defined $ts) {
+ $ts = msg_timestamp($mime);
+ }
+ my $fmt = '%Y-%m-%d %H:%M';
$ts = POSIX::strftime($fmt, gmtime($ts));
$rv .= "$pfx<b\nid=\"$id\">$subj</b>\n$pfx";
- $rv .= "- by $from @ $ts - ";
+ $rv .= "- by $from @ $ts UTC - ";
$rv .= "<a\nid=\"s$midx\"\nhref=\"#s$next\">next</a>";
if ($prev >= 0) {
$rv .= "/<a\nhref=\"#s$prev\">prev</a>";
@@ -583,13 +586,17 @@ sub load_results {
Email::MIME->new($str);
};
unless ($@) {
- my $t = eval { str2time($mime->header('Date')) };
- defined($t) or $t = 0;
- $mime->header_set('X-PI-TS', $t);
+ $mime->header_set('X-PI-TS', msg_timestamp($mime));
push @msgs, $mime;
}
}
\@msgs;
}
+sub msg_timestamp {
+ my ($mime) = @_;
+ my $ts = eval { str2time($mime->header('Date')) };
+ defined($ts) ? $ts : 0;
+}
+
1;
--
EW
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 03/11] use tables for rendering comment nesting
2015-08-20 2:57 [PATCH 01/11] feed: remove threading from index Eric Wong
2015-08-20 2:57 ` [PATCH 02/11] feed: move timestamp parsing to view Eric Wong
@ 2015-08-20 2:57 ` Eric Wong
2015-08-20 2:57 ` [PATCH 04/11] view: avoid nesting <a> tags from auto-linkification Eric Wong
` (7 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Eric Wong @ 2015-08-20 2:57 UTC (permalink / raw)
To: meta
This is more space efficient since we don't need to place padding
bytes in front of every line. While this unfortunately does not
render well on lynx; w3m, links, elinks can all render tables
sanely.
Tables are also superior for long lines which require wrapping
inside <pre> containers.
---
lib/PublicInbox/Feed.pm | 7 +++----
lib/PublicInbox/View.pm | 43 ++++++++++++++++++-------------------------
2 files changed, 21 insertions(+), 29 deletions(-)
diff --git a/lib/PublicInbox/Feed.pm b/lib/PublicInbox/Feed.pm
index 0b7ef7f..8bfd19e 100644
--- a/lib/PublicInbox/Feed.pm
+++ b/lib/PublicInbox/Feed.pm
@@ -12,7 +12,6 @@ use PublicInbox::View;
use constant {
DATEFMT => '%Y-%m-%dT%H:%M:%SZ', # atom standard
MAX_PER_PAGE => 25, # this needs to be tunable
- PRE_WRAP => "<pre\nstyle=\"white-space:pre-wrap\">",
};
# main function
@@ -60,7 +59,7 @@ sub generate_html_index {
my $html = "<html><head><title>$title</title>" .
'<link rel="alternate" title="Atom feed"' . "\nhref=\"" .
$feed_opts->{atomurl} . "\"\ntype=\"application/atom+xml\"/>" .
- '</head><body>' . PRE_WRAP;
+ '</head><body>';
my $state;
my $git = PublicInbox::GitCatFile->new($ctx->{git_dir});
@@ -80,9 +79,9 @@ sub generate_html_index {
if ($footer) {
my $list_footer = $ctx->{footer};
$footer .= "\n" . $list_footer if $list_footer;
- $footer = "<hr />" . PRE_WRAP . "$footer</pre>";
+ $footer = "<hr /><pre>$footer</pre>";
}
- $html . "</pre>$footer</body></html>";
+ $html .= "$footer</body></html>";
}
# private subs
diff --git a/lib/PublicInbox/View.pm b/lib/PublicInbox/View.pm
index 4a8e54a..800c1a2 100644
--- a/lib/PublicInbox/View.pm
+++ b/lib/PublicInbox/View.pm
@@ -33,8 +33,9 @@ sub msg_html {
}
headers_to_html_header($mime, $full_pfx, $srch) .
multipart_text_as_html($mime, $full_pfx) .
- '</pre><hr />' . PRE_WRAP .
- html_footer($mime, 1, $full_pfx, $srch) . $footer .
+ '</pre><hr /><pre>' .
+ html_footer($mime, 1, $full_pfx, $srch) .
+ $footer .
'</pre></body></html>';
}
@@ -51,7 +52,6 @@ sub index_entry {
my ($srch, $seen, $first_commit) = @$state;
my $midx = $state->[3]++;
my ($prev, $next) = ($midx - 1, $midx + 1);
- my $rv = '';
my $part_nr = 0;
my $enc_msg = enc_for($mime->header("Content-Type"));
my $subj = $mime->header('Subject');
@@ -69,15 +69,9 @@ sub index_entry {
$from = PublicInbox::Hval->new_oneline($from)->as_html;
$subj = PublicInbox::Hval->new_oneline($subj)->as_html;
- my $pfx = (' ' x $level);
my $root_anchor = $seen->{root_anchor};
- my $path;
my $more = 'permalink';
- if ($root_anchor) {
- $path = '../';
- } else {
- $path = '';
- }
+ my $path = $root_anchor ? '../' : '';
my $href = $mid->as_href;
my $irt = $header_obj->header_raw('In-Reply-To');
my ($anchor_idx, $anchor, $t_anchor);
@@ -88,7 +82,6 @@ sub index_entry {
} else {
$t_anchor = '';
}
-
if (defined $srch) {
$subj = "<a\nhref=\"${path}t/$href.html#u\">$subj</a>";
}
@@ -103,7 +96,12 @@ sub index_entry {
my $fmt = '%Y-%m-%d %H:%M';
$ts = POSIX::strftime($fmt, gmtime($ts));
- $rv .= "$pfx<b\nid=\"$id\">$subj</b>\n$pfx";
+ my $rv = "<table\nsummary=l$level><tr>";
+ if ($level) {
+ $rv .= '<td><pre>' . (' ' x $level) . '</pre></td>';
+ }
+ $rv .= '<td>' . PRE_WRAP;
+ $rv .= "<b\nid=\"$id\">$subj</b>\n";
$rv .= "- by $from @ $ts UTC - ";
$rv .= "<a\nid=\"s$midx\"\nhref=\"#s$next\">next</a>";
if ($prev >= 0) {
@@ -115,13 +113,12 @@ sub index_entry {
my $fhref = "${path}f/$href.html";
# scan through all parts, looking for displayable text
$mime->walk_parts(sub {
- $rv .= index_walk($_[0], $pfx, $enc_msg, $part_nr, $fhref,
- \$more);
+ $rv .= index_walk($_[0], $enc_msg, $part_nr, $fhref, \$more);
$part_nr++;
});
$mime->body_set('');
- $rv .= "\n$pfx<a\nhref=\"$mhref\">$more</a> ";
+ $rv .= "\n<a\nhref=\"$mhref\">$more</a> ";
my $txt = "${path}m/$href.txt";
$rv .= "<a\nhref=\"$txt\">raw</a> ";
$rv .= html_footer($mime, 0);
@@ -141,7 +138,7 @@ sub index_entry {
"threadlink</a>";
}
- $rv . "\n\n";
+ $rv .= '</pre></td></tr></table>';
}
sub thread_html {
@@ -168,7 +165,7 @@ sub thread_html {
}
$next .= "</a>, back to <a\nhref=\"../\">index</a>\n";
- $rv .= "</pre><hr />" . PRE_WRAP . $next . $foot . "</pre>";
+ $rv .= "<hr />" . PRE_WRAP . $next . $foot . "</pre>";
}
sub subject_path_html {
@@ -188,13 +185,13 @@ sub subject_path_html {
my $final_anchor = $state->[3];
my $next = "<a\nid=\"s$final_anchor\">end of thread</a>\n";
- $rv .= "</pre><hr />" . PRE_WRAP . $next . $foot . "</pre>";
+ $rv .= "<hr />" . PRE_WRAP . $next . $foot . "</pre>";
}
# only private functions below.
sub index_walk {
- my ($part, $pfx, $enc_msg, $part_nr, $fhref, $more) = @_;
+ my ($part, $enc_msg, $part_nr, $fhref, $more) = @_;
my $rv = '';
return $rv if $part->subparts; # walk_parts already recurses
my $ct = $part->content_type;
@@ -207,7 +204,7 @@ sub index_walk {
if ($part_nr > 0) {
my $fn = $part->filename;
defined($fn) or $fn = "part #" . ($part_nr + 1);
- $rv .= $pfx . add_filename_line($enc->decode($fn));
+ $rv .= add_filename_line($enc->decode($fn));
}
my $s = add_text_body_short($enc, $part, $part_nr, $fhref);
@@ -224,9 +221,6 @@ sub index_walk {
$s =~ s/\s+\z//s;
if (length $s) {
- # add prefix:
- $s =~ s/^/$pfx/sgm;
-
# kill per-line trailing whitespace
$s =~ s/[ \t]+$//sgm;
@@ -549,8 +543,7 @@ sub thread_html_head {
my ($mime) = @_;
my $s = PublicInbox::Hval->new_oneline($mime->header('Subject'));
$s = $s->as_html;
- "<html><head><title>$s</title></head><body>" . PRE_WRAP
-
+ "<html><head><title>$s</title></head><body>";
}
sub thread_entry {
--
EW
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 04/11] view: avoid nesting <a> tags from auto-linkification
2015-08-20 2:57 [PATCH 01/11] feed: remove threading from index Eric Wong
2015-08-20 2:57 ` [PATCH 02/11] feed: move timestamp parsing to view Eric Wong
2015-08-20 2:57 ` [PATCH 03/11] use tables for rendering comment nesting Eric Wong
@ 2015-08-20 2:57 ` Eric Wong
2015-08-20 2:57 ` [PATCH 05/11] index: simplify main landing page if search-enabled Eric Wong
` (6 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Eric Wong @ 2015-08-20 2:57 UTC (permalink / raw)
To: meta
It is wrong HTML to have <a> tags nested due to auto-linkification.
---
lib/PublicInbox/View.pm | 110 +++++++++++++++++++++++++++---------------------
t/view.t | 2 +-
2 files changed, 62 insertions(+), 50 deletions(-)
diff --git a/lib/PublicInbox/View.pm b/lib/PublicInbox/View.pm
index 800c1a2..2ba5118 100644
--- a/lib/PublicInbox/View.pm
+++ b/lib/PublicInbox/View.pm
@@ -207,7 +207,7 @@ sub index_walk {
$rv .= add_filename_line($enc->decode($fn));
}
- my $s = add_text_body_short($enc, $part, $part_nr, $fhref);
+ my $s = add_text_body($enc, $part, $part_nr, $fhref);
# drop the remainder of git patches, they're usually better
# to review when the full message is viewed
@@ -266,12 +266,7 @@ sub multipart_text_as_html {
$rv .= add_filename_line($enc->decode($fn));
}
- if (defined $full_pfx) {
- $rv .= add_text_body_short($enc, $part, $part_nr,
- $full_pfx);
- } else {
- $rv .= add_text_body_full($enc, $part, $part_nr);
- }
+ $rv .= add_text_body($enc, $part, $part_nr, $full_pfx);
$rv .= "\n" unless $rv =~ /\n\z/s;
++$part_nr;
});
@@ -294,57 +289,74 @@ my $LINK_RE = qr!\b((?:ftp|https?|nntp)://[@\w\+\&\?\.\%\;/#=-]+)!;
sub linkify {
# no newlines added here since it'd break the splitting we do
# to fold quotes
- $_[0] =~ s!$LINK_RE!<a href="$1">$1</a>!g;
+ $_[0] =~ s!$LINK_RE!<a\nhref="$1">$1</a>!g;
}
-sub add_text_body_short {
- my ($enc, $part, $part_nr, $full_pfx) = @_;
- my $n = 0;
- my $s = ascii_html($enc->decode($part->body));
- linkify($s);
- $s =~ s!^((?:(?:>[^\n]*)\n)+)!
- my $cur = $1;
- my @lines = split(/\n/, $cur);
- if (@lines > MAX_INLINE_QUOTED) {
- # show a short snippet of quoted text
- $cur = join(' ', @lines);
- $cur =~ s/^>\s*//;
-
- my @sum = split(/\s+/, $cur);
- $cur = '';
- do {
- my $tmp = shift(@sum);
- my $len = length($tmp) + length($cur);
- if ($len > MAX_TRUNC_LEN) {
- @sum = ();
- } else {
- $cur .= $tmp . ' ';
- }
- } while (@sum && length($cur) < MAX_TRUNC_LEN);
- $cur =~ s/ \z/ .../;
- "> <<a\nhref=\"${full_pfx}#q${part_nr}_" . $n++ .
- "\">$cur<\/a>>\n";
- } else {
- $cur;
+sub flush_quote {
+ my ($quot, $n, $part_nr, $full_pfx, $final) = @_;
+
+ if ($full_pfx) {
+ if (!$final && scalar(@$quot) <= MAX_INLINE_QUOTED) {
+ # show quote inline
+ my $rv = join("\n", map { linkify($_); $_ } @$quot);
+ @$quot = ();
+ return $rv . "\n";
}
- !emg;
- $s;
+
+ # show a short snippet of quoted text and link to full version:
+ @$quot = map { s/^(?:>\s*)+//gm; $_ } @$quot;
+ my $cur = join(' ', @$quot);
+ @$quot = split(/\s+/, $cur);
+ $cur = '';
+ do {
+ my $tmp = shift(@$quot);
+ my $len = length($tmp) + length($cur);
+ if ($len > MAX_TRUNC_LEN) {
+ @$quot = ();
+ } else {
+ $cur .= $tmp . ' ';
+ }
+ } while (@$quot && length($cur) < MAX_TRUNC_LEN);
+ @$quot = ();
+ $cur =~ s/ \z/ .../s;
+ my $nr = ++$$n;
+ "> [<a\nhref=\"$full_pfx#q${part_nr}_$nr\">$cur</a>]\n";
+ } else {
+ # show everything in the full version with anchor from
+ # short version (see above)
+ my $nr = ++$$n;
+ my $rv = "<a\nid=q${part_nr}_$nr></a>";
+ $rv .= join("\n", map { linkify($_); $_ } @$quot) . "\n";
+ @$quot = ();
+ $rv;
+ }
}
-sub add_text_body_full {
- my ($enc, $part, $part_nr) = @_;
+sub add_text_body {
+ my ($enc, $part, $part_nr, $full_pfx) = @_;
my $n = 0;
my $s = ascii_html($enc->decode($part->body));
- linkify($s);
- $s =~ s!^((?:(?:>[^\n]*)\n)+)!
- my $cur = $1;
- my @lines = split(/\n/, $cur);
- if (@lines > MAX_INLINE_QUOTED) {
- "<a\nid=q${part_nr}_" . $n++ . ">$cur</a>";
+ my @lines = split(/\n/, $s);
+ $s = '';
+ my $nr = 0;
+ my @quot;
+ while (defined(my $cur = shift @lines)) {
+ if ($cur !~ /^>/) {
+ # show the previously buffered quote inline
+ if (scalar @quot) {
+ $s .= flush_quote(\@quot, \$n, $part_nr,
+ $full_pfx, 0);
+ }
+
+ # regular line, OK
+ linkify($cur);
+ $s .= $cur;
+ $s .= "\n";
} else {
- $cur;
+ push @quot, $cur;
}
- !emg;
+ }
+ $s .= flush_quote(\@quot, \$n, $part_nr, $full_pfx, 1) if scalar @quot;
$s;
}
diff --git a/t/view.t b/t/view.t
index 463fc07..ca456aa 100644
--- a/t/view.t
+++ b/t/view.t
@@ -47,7 +47,7 @@ EOF
like($html, qr!<a\nhref="\.\./m/hello%40!s, "MID link present");
like($html, qr/hello world\b/, "body present");
like($html, qr/> keep this inline/, "short quoted text is inline");
- like($html, qr/<a\nid=[^>]+>> Long and wordy/,
+ like($html, qr/<a\nid=[^>]+><\/a>> Long and wordy/,
"long quoted text is anchored");
# short page
--
EW
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 05/11] index: simplify main landing page if search-enabled
2015-08-20 2:57 [PATCH 01/11] feed: remove threading from index Eric Wong
` (2 preceding siblings ...)
2015-08-20 2:57 ` [PATCH 04/11] view: avoid nesting <a> tags from auto-linkification Eric Wong
@ 2015-08-20 2:57 ` Eric Wong
2015-08-20 2:57 ` [PATCH 06/11] search: avoid needless decode Eric Wong
` (5 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Eric Wong @ 2015-08-20 2:57 UTC (permalink / raw)
To: meta
We can display /t/$MESSAGE_ID.html easily with a Xapian search
index, so rely on it instead of trying to display messages inline.
---
lib/PublicInbox/Feed.pm | 103 +++++++++++++++++++++++++++++++++++++++-------
lib/PublicInbox/Search.pm | 15 +++++--
2 files changed, 98 insertions(+), 20 deletions(-)
diff --git a/lib/PublicInbox/Feed.pm b/lib/PublicInbox/Feed.pm
index 8bfd19e..40dfb45 100644
--- a/lib/PublicInbox/Feed.pm
+++ b/lib/PublicInbox/Feed.pm
@@ -9,11 +9,15 @@ use Date::Parse qw(strptime);
use PublicInbox::Hval;
use PublicInbox::GitCatFile;
use PublicInbox::View;
+use PublicInbox::MID qw/mid_clean mid_compressed/;
use constant {
DATEFMT => '%Y-%m-%dT%H:%M:%SZ', # atom standard
MAX_PER_PAGE => 25, # this needs to be tunable
};
+use Encode qw/find_encoding/;
+my $enc_utf8 = find_encoding('UTF-8');
+
# main function
sub generate {
my ($class, $ctx) = @_;
@@ -55,22 +59,30 @@ sub generate_html_index {
my $title = $feed_opts->{description} || '';
$title = PublicInbox::Hval->new_oneline($title)->as_html;
+ my $atom_url = $feed_opts->{atomurl};
my $html = "<html><head><title>$title</title>" .
- '<link rel="alternate" title="Atom feed"' . "\nhref=\"" .
- $feed_opts->{atomurl} . "\"\ntype=\"application/atom+xml\"/>" .
- '</head><body>';
+ "<link\nrel=alternate\ntitle=\"Atom feed\"\n".
+ "href=\"$atom_url\"\"\ntype=\"application/atom+xml\"/>" .
+ '</head><body>' . PublicInbox::View::PRE_WRAP;
my $state;
my $git = PublicInbox::GitCatFile->new($ctx->{git_dir});
+ my $topics;
+ my $srch = $ctx->{srch};
+ $srch and $topics = [ [], {} ];
my (undef, $last) = each_recent_blob($ctx, sub {
- my ($path, $commit) = @_;
- unless (defined $state) {
- $state = [ $ctx->{srch}, {}, $commit, 0 ];
+ my ($path, $commit, $ts, $u, $subj) = @_;
+ $state ||= [ undef, {}, $commit, 0 ];
+
+ if ($srch) {
+ add_topic($git, $srch, $topics, $path, $ts, $u, $subj);
+ } else {
+ my $mime = do_cat_mail($git, $path) or return 0;
+ $html .=
+ PublicInbox::View->index_entry($mime, 0, $state);
+ 1;
}
- my $mime = do_cat_mail($git, $_[0]) or return 0;
- $html .= PublicInbox::View->index_entry($mime, 0, $state);
- 1;
});
Email::Address->purge_cache;
$git = undef; # destroy pipes.
@@ -81,6 +93,7 @@ sub generate_html_index {
$footer .= "\n" . $list_footer if $list_footer;
$footer = "<hr /><pre>$footer</pre>";
}
+ dump_topics(\$html, $topics) if $topics;
$html .= "$footer</body></html>";
}
@@ -92,6 +105,7 @@ sub nav_footer {
my $old_r = $cgi->param('r');
my $head = ' ';
my $next = ' ';
+ # $state = [ undef, {}, $first_commit, $last_anchor ];
my $first = $state->[2];
my $anchor = $state->[3];
@@ -128,7 +142,8 @@ sub each_recent_blob {
# leave us with filenames with spaces in them..
my @cmd = ('git', "--git-dir=$ctx->{git_dir}",
qw/log --no-notes --no-color --raw -r
- --abbrev=16 --abbrev-commit/);
+ --abbrev=16 --abbrev-commit/,
+ "--format=%h%x00%ct%x00%an%x00%s%x00");
push @cmd, $range;
my $pid = open(my $log, '-|', @cmd) or
@@ -137,26 +152,29 @@ sub each_recent_blob {
my $last;
my $nr = 0;
my ($cur_commit, $first_commit, $last_commit);
- while (my $line = <$log>) {
+ my ($ts, $subj, $u);
+ while (defined(my $line = <$log>)) {
if ($line =~ /$addmsg/o) {
my $add = $1;
next if $deleted{$add}; # optimization-only
- $nr += $cb->($add, $cur_commit);
+ $nr += $cb->($add, $cur_commit, $ts, $u, $subj);
if ($nr >= $max) {
$last = 1;
last;
}
} elsif ($line =~ /$delmsg/o) {
$deleted{$1} = 1;
- } elsif ($line =~ /^commit (${hex}{7,40})/o) {
- $cur_commit = $1;
- $first_commit = $1 unless defined $first_commit;
+ } elsif ($line =~ /^${hex}{7,40}/o) {
+ ($cur_commit, $ts, $u, $subj) = split("\0", $line);
+ unless (defined $first_commit) {
+ $first_commit = $cur_commit;
+ }
}
}
if ($last) {
while (my $line = <$log>) {
- if ($line =~ /^commit (${hex}{7,40})/o) {
+ if ($line =~ /^(${hex}{7,40})/o) {
$last_commit = $1;
last;
}
@@ -279,4 +297,57 @@ sub do_cat_mail {
$@ ? undef : $mime;
}
+# accumulate recent topics if search is supported
+sub add_topic {
+ my ($git, $srch, $topics, $path, $ts, $u, $subj) = @_;
+ my ($order, $subjs) = @$topics;
+ my $header_obj;
+
+ # legacy ssoma did not set commit titles based on Subject
+ $subj = $enc_utf8->decode($subj);
+ if ($subj eq 'mda') {
+ my $mime = do_cat_mail($git, $path) or return 0;
+ $header_obj = $mime->header_obj;
+ $subj = mime_header($header_obj, 'Subject');
+ }
+
+ $subj = $srch->subject_normalized($subj);
+ if (++$subjs->{$subj} == 1) {
+ unless ($header_obj) {
+ my $mime = do_cat_mail($git, $path) or return 0;
+ $header_obj = $mime->header_obj;
+ }
+ my $mid = $header_obj->header_raw('Message-ID');
+ $mid = mid_compressed(mid_clean($mid));
+ $u = $enc_utf8->decode($u);
+ push @$order, [ $mid, $ts, $u, $subj ];
+ return 1;
+ }
+ 0; # old topic, continue going
+}
+
+sub dump_topics {
+ my ($dst, $topics) = @_;
+ my ($order, $subjs) = @$topics;
+ $$dst .= '[No recent topics]' unless (scalar @$order);
+ while (defined(my $info = shift @$order)) {
+ my ($mid, $ts, $u, $subj) = @$info;
+ my $n = delete $subjs->{$subj};
+ $mid = PublicInbox::Hval->new($mid)->as_href;
+ $subj = PublicInbox::Hval->new($subj)->as_html;
+ $u = PublicInbox::Hval->new($u)->as_html;
+ $$dst .= "<a\nhref=\"t/$mid.html#u\"><b>$subj</b></a>\n- ";
+ $ts = POSIX::strftime('%Y-%m-%d %H:%M', gmtime($ts));
+ if ($n == 1) {
+ $$dst .= "created by $u @ $ts UTC\n"
+ } else {
+ # $n isn't the total number of posts on the topic,
+ # just the number of posts in the current "git log"
+ # window, so leave it unlabeled
+ $$dst .= "updated by $u @ $ts UTC ($n)\n"
+ }
+ }
+ $$dst .= '</pre>'
+}
+
1;
diff --git a/lib/PublicInbox/Search.pm b/lib/PublicInbox/Search.pm
index b9f283f..c28401b 100644
--- a/lib/PublicInbox/Search.pm
+++ b/lib/PublicInbox/Search.pm
@@ -492,14 +492,21 @@ sub merge_threads {
# normalize subjects so they are suitable as pathnames for URLs
sub subject_path {
my $subj = pop;
-
- $subj =~ s/\A\s+//;
- $subj =~ s/\s+\z//;
- $subj =~ s/$REPLY_RE//igo; # remove reply prefix
+ $subj = subject_normalized($subj);
$subj =~ s![^a-zA-Z0-9_\.~/\-]+!_!g;
lc($subj);
}
+sub subject_normalized {
+ my $subj = pop;
+ $subj =~ s/\A\s+//s; # no leading space
+ $subj =~ s/\s+\z//s; # no trailing space
+ $subj =~ s/\s+/ /gs; # no redundant spaces
+ $subj =~ s/\.+\z//; # no trailing '.'
+ $subj =~ s/$REPLY_RE//igo; # remove reply prefix
+ $subj;
+}
+
sub do_cat_mail {
my ($git, $blob) = @_;
my $mime = eval {
--
EW
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 06/11] search: avoid needless decode
2015-08-20 2:57 [PATCH 01/11] feed: remove threading from index Eric Wong
` (3 preceding siblings ...)
2015-08-20 2:57 ` [PATCH 05/11] index: simplify main landing page if search-enabled Eric Wong
@ 2015-08-20 2:57 ` Eric Wong
2015-08-20 2:57 ` [PATCH 07/11] search: reject ghosts in all cases Eric Wong
` (4 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Eric Wong @ 2015-08-20 2:57 UTC (permalink / raw)
To: meta
Email::MIME should handle everything for us and make things
work nicely with Xapian (assuming I understand how encoding
works in Perl).
While we're at it, reduce temporary strings and arrays by
using destructive operations and clobbering parts as we
iterate through them.
---
lib/PublicInbox/Search.pm | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/lib/PublicInbox/Search.pm b/lib/PublicInbox/Search.pm
index c28401b..aa29ae5 100644
--- a/lib/PublicInbox/Search.pm
+++ b/lib/PublicInbox/Search.pm
@@ -6,7 +6,6 @@ use strict;
use warnings;
use PublicInbox::SearchMsg;
use Search::Xapian qw/:standard/;
-require PublicInbox::View;
use Email::MIME;
use PublicInbox::MID qw/mid_clean mid_compressed/;
@@ -88,7 +87,6 @@ sub add_message {
my $mid = mid_compressed($mid_orig);
my $was_ghost = 0;
my $ct_msg = $mime->header('Content-Type') || 'text/plain';
- my $enc_msg = PublicInbox::View::enc_for($ct_msg);
eval {
my $smsg = $self->lookup_message($mid);
@@ -151,9 +149,11 @@ sub add_message {
# account for filter bugs...
$ct =~ m!\btext/plain\b!i or return;
- my $enc = PublicInbox::View::enc_for($ct, $enc_msg);
my (@orig, @quot);
- foreach my $l (split(/\n/, $enc->decode($part->body))) {
+ my $body = $part->body;
+ $part->body_set('');
+ my @lines = split(/\n/, $body);
+ while (defined(my $l = shift @lines)) {
if ($l =~ /^\s*>/) {
push @quot, $l;
} else {
@@ -162,10 +162,12 @@ sub add_message {
}
if (@quot) {
$tg->index_text(join("\n", @quot), 0);
+ @quot = ();
$tg->increase_termpos;
}
if (@orig) {
$tg->index_text(join("\n", @orig));
+ @orig = ();
$tg->increase_termpos;
}
});
--
EW
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 07/11] search: reject ghosts in all cases
2015-08-20 2:57 [PATCH 01/11] feed: remove threading from index Eric Wong
` (4 preceding siblings ...)
2015-08-20 2:57 ` [PATCH 06/11] search: avoid needless decode Eric Wong
@ 2015-08-20 2:57 ` Eric Wong
2015-08-20 2:57 ` [PATCH 08/11] view: reduce memory usage when displaying large threads Eric Wong
` (3 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Eric Wong @ 2015-08-20 2:57 UTC (permalink / raw)
To: meta
We do not need ghost messages in any of our thread views
---
lib/PublicInbox/Search.pm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/PublicInbox/Search.pm b/lib/PublicInbox/Search.pm
index aa29ae5..0e63ee3 100644
--- a/lib/PublicInbox/Search.pm
+++ b/lib/PublicInbox/Search.pm
@@ -214,7 +214,6 @@ sub query {
my ($self, $query_string, $opts) = @_;
my $query = $self->qp->parse_query($query_string, QP_FLAGS);
- $query = Search::Xapian::Query->new(OP_AND, $mail_query, $query);
$self->do_enquire($query, $opts);
}
@@ -255,6 +254,7 @@ sub do_enquire {
my ($self, $query, $opts) = @_;
my $enquire = $self->enquire;
+ $query = Search::Xapian::Query->new(OP_AND, $query, $mail_query);
$enquire->set_query($query);
$enquire->set_sort_by_relevance_then_value(TS, 0);
$opts ||= {};
--
EW
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 08/11] view: reduce memory usage when displaying large threads
2015-08-20 2:57 [PATCH 01/11] feed: remove threading from index Eric Wong
` (5 preceding siblings ...)
2015-08-20 2:57 ` [PATCH 07/11] search: reject ghosts in all cases Eric Wong
@ 2015-08-20 2:57 ` Eric Wong
2015-08-20 2:57 ` [PATCH 09/11] search: bump schema version to 5 for subject_path Eric Wong
` (2 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Eric Wong @ 2015-08-20 2:57 UTC (permalink / raw)
To: meta
We want to minimize the time any large objects or strings
are referenced. We can do threading entirely from the
mini_mime-generated messages and lazilly load full messages
when rendering the display.
---
lib/PublicInbox/View.pm | 80 +++++++++++++++++++++++++++----------------------
1 file changed, 44 insertions(+), 36 deletions(-)
diff --git a/lib/PublicInbox/View.pm b/lib/PublicInbox/View.pm
index 2ba5118..391e3ad 100644
--- a/lib/PublicInbox/View.pm
+++ b/lib/PublicInbox/View.pm
@@ -146,7 +146,7 @@ sub thread_html {
my $mid = mid_compressed($ctx->{mid});
my $res = $srch->get_thread($mid);
my $rv = '';
- my $msgs = load_results($ctx, $res);
+ my $msgs = load_results($res);
my $nr = scalar @$msgs;
return $rv if $nr == 0;
require PublicInbox::Thread;
@@ -154,7 +154,11 @@ sub thread_html {
$th->thread;
$th->order(*PublicInbox::Thread::sort_ts);
my $state = [ $srch, { root_anchor => anchor_for($mid) }, undef, 0 ];
- thread_entry(\$rv, $state, $_, 0) for $th->rootset;
+ {
+ require PublicInbox::GitCatFile;
+ my $git = PublicInbox::GitCatFile->new($ctx->{git_dir});
+ thread_entry(\$rv, $git, $state, $_, 0) for $th->rootset;
+ }
my $final_anchor = $state->[3];
my $next = "<a\nid=\"s$final_anchor\">";
@@ -173,7 +177,7 @@ sub subject_path_html {
my $path = $ctx->{subject_path};
my $res = $srch->get_subject_path($path);
my $rv = '';
- my $msgs = load_results($ctx, $res);
+ my $msgs = load_results($res);
my $nr = scalar @$msgs;
return $rv if $nr == 0;
require PublicInbox::Thread;
@@ -181,7 +185,11 @@ sub subject_path_html {
$th->thread;
$th->order(*PublicInbox::Thread::sort_ts);
my $state = [ $srch, { root_anchor => 'dummy' }, undef, 0 ];
- thread_entry(\$rv, $state, $_, 0) for $th->rootset;
+ {
+ require PublicInbox::GitCatFile;
+ my $git = PublicInbox::GitCatFile->new($ctx->{git_dir});
+ thread_entry(\$rv, $git, $state, $_, 0) for $th->rootset;
+ }
my $final_anchor = $state->[3];
my $next = "<a\nid=\"s$final_anchor\">end of thread</a>\n";
@@ -197,7 +205,10 @@ sub index_walk {
my $ct = $part->content_type;
# account for filter bugs...
- return '' if defined $ct && $ct =~ m!\btext/[xh]+tml\b!i;
+ if (defined $ct && $ct =~ m!\btext/[xh]+tml\b!i) {
+ $part->body_set('');
+ return '';
+ }
my $enc = enc_for($ct, $enc_msg);
@@ -224,7 +235,9 @@ sub index_walk {
# kill per-line trailing whitespace
$s =~ s/[ \t]+$//sgm;
- $rv .= $s . "\n";
+ $rv .= $s;
+ $s = undef;
+ $rv .= "\n";
}
$rv;
}
@@ -335,10 +348,13 @@ sub flush_quote {
sub add_text_body {
my ($enc, $part, $part_nr, $full_pfx) = @_;
my $n = 0;
- my $s = ascii_html($enc->decode($part->body));
+ my $nr = 0;
+ my $s = $part->body;
+ $part->body_set('');
+ $s = $enc->decode($s);
+ $s = ascii_html($s);
my @lines = split(/\n/, $s);
$s = '';
- my $nr = 0;
my @quot;
while (defined(my $cur = shift @lines)) {
if ($cur !~ /^>/) {
@@ -538,10 +554,10 @@ sub simple_dump {
sub thread_followups {
my ($dst, $root, $res) = @_;
- my @msgs = map { $_->mini_mime } @{$res->{msgs}};
+ my $msgs = load_results($res);
require PublicInbox::Thread;
$root->header_set('X-PI-TS', '0');
- my $th = PublicInbox::Thread->new($root, @msgs);
+ my $th = PublicInbox::Thread->new($root, @$msgs);
$th->thread;
$th->order(*PublicInbox::Thread::sort_ts);
my $srch = $res->{srch};
@@ -559,43 +575,35 @@ sub thread_html_head {
}
sub thread_entry {
- my ($dst, $state, $node, $level) = @_;
+ my ($dst, $git, $state, $node, $level) = @_;
# $state = [ $search_res, $seen, undef, 0 (msg_nr) ];
# $seen is overloaded with 3 types of fields:
# 1) "root_anchor" => anchor_for(Message-ID),
# 2) seen subject hashes: sha1(subject) => 1
# 3) anchors hashes: "#$sha1_hex" (same as $seen in index_entry)
if (my $mime = $node->message) {
- if (length($$dst) == 0) {
- $$dst .= thread_html_head($mime);
+
+ # lazy load the full message from mini_mime:
+ my $path = mid2path(mid_clean($mime->header('Message-ID')));
+ $mime = eval { Email::MIME->new($git->cat_file("HEAD:$path")) };
+ if ($mime) {
+ if (length($$dst) == 0) {
+ $$dst .= thread_html_head($mime);
+ }
+ $$dst .= index_entry(undef, $mime, $level, $state);
}
- $$dst .= index_entry(undef, $mime, $level, $state);
}
- thread_entry($dst, $state, $node->child, $level + 1) if $node->child;
- thread_entry($dst, $state, $node->next, $level) if $node->next;
+ my $cur;
+ $cur = $node->child and
+ thread_entry($dst, $git, $state, $cur, $level + 1);
+ $cur = $node->next and
+ thread_entry($dst, $git, $state, $cur, $level);
}
sub load_results {
- my ($ctx, $res) = @_;
-
- require PublicInbox::GitCatFile;
- my $git = PublicInbox::GitCatFile->new($ctx->{git_dir});
- my @msgs;
- while (my $smsg = shift @{$res->{msgs}}) {
- my $m = $smsg->mid;
- my $path = mid2path($m);
-
- # FIXME: duplicated code from Feed.pm
- my $mime = eval {
- my $str = $git->cat_file("HEAD:$path");
- Email::MIME->new($str);
- };
- unless ($@) {
- $mime->header_set('X-PI-TS', msg_timestamp($mime));
- push @msgs, $mime;
- }
- }
- \@msgs;
+ my ($res) = @_;
+
+ [ map { $_->mini_mime } @{delete $res->{msgs}} ];
}
sub msg_timestamp {
--
EW
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 09/11] search: bump schema version to 5 for subject_path
2015-08-20 2:57 [PATCH 01/11] feed: remove threading from index Eric Wong
` (6 preceding siblings ...)
2015-08-20 2:57 ` [PATCH 08/11] view: reduce memory usage when displaying large threads Eric Wong
@ 2015-08-20 2:57 ` Eric Wong
2015-08-20 2:57 ` [PATCH 10/11] index: layout fix + title and Atom feed links at top Eric Wong
2015-08-20 2:57 ` [PATCH 11/11] view: do not fold top-level messages in thread Eric Wong
9 siblings, 0 replies; 11+ messages in thread
From: Eric Wong @ 2015-08-20 2:57 UTC (permalink / raw)
To: meta
In "index: simplify main landing page if search-enabled",
subject normalization went a little farther to drop trailing
'.' characters, so we will need to re-index.
---
lib/PublicInbox/Search.pm | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/lib/PublicInbox/Search.pm b/lib/PublicInbox/Search.pm
index 0e63ee3..abd9db4 100644
--- a/lib/PublicInbox/Search.pm
+++ b/lib/PublicInbox/Search.pm
@@ -22,7 +22,8 @@ use constant {
# 2 - subject_path is mid_compressed in the index, only
# 3 - message-ID is compressed if it includes '%' (hack!)
# 4 - change "Re: " normalization, avoid circular Reference ghosts
- SCHEMA_VERSION => 4,
+ # 5 - subject_path drops trailing '.'
+ SCHEMA_VERSION => 5,
QP_FLAGS => FLAG_PHRASE|FLAG_BOOLEAN|FLAG_LOVEHATE|FLAG_WILDCARD,
};
--
EW
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 10/11] index: layout fix + title and Atom feed links at top
2015-08-20 2:57 [PATCH 01/11] feed: remove threading from index Eric Wong
` (7 preceding siblings ...)
2015-08-20 2:57 ` [PATCH 09/11] search: bump schema version to 5 for subject_path Eric Wong
@ 2015-08-20 2:57 ` Eric Wong
2015-08-20 2:57 ` [PATCH 11/11] view: do not fold top-level messages in thread Eric Wong
9 siblings, 0 replies; 11+ messages in thread
From: Eric Wong @ 2015-08-20 2:57 UTC (permalink / raw)
To: meta
Add some spacing between topics to improve readability when
scanning or in case a subject gets too long.
The title and Atom feed may not be highly-visible otherwise.
While we're at it, use the proper "Atom feed" terminology since
some folks may not understand just what "atom" means.
---
lib/PublicInbox/Feed.pm | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/lib/PublicInbox/Feed.pm b/lib/PublicInbox/Feed.pm
index 40dfb45..2e352cb 100644
--- a/lib/PublicInbox/Feed.pm
+++ b/lib/PublicInbox/Feed.pm
@@ -64,7 +64,8 @@ sub generate_html_index {
my $html = "<html><head><title>$title</title>" .
"<link\nrel=alternate\ntitle=\"Atom feed\"\n".
"href=\"$atom_url\"\"\ntype=\"application/atom+xml\"/>" .
- '</head><body>' . PublicInbox::View::PRE_WRAP;
+ '</head><body>' . PublicInbox::View::PRE_WRAP .
+ "<b>$title</b> (<a\nhref=\"$atom_url\">Atom feed</a>)\n";
my $state;
my $git = PublicInbox::GitCatFile->new($ctx->{git_dir});
@@ -329,14 +330,14 @@ sub add_topic {
sub dump_topics {
my ($dst, $topics) = @_;
my ($order, $subjs) = @$topics;
- $$dst .= '[No recent topics]' unless (scalar @$order);
+ $$dst .= "\n[No recent topics]" unless (scalar @$order);
while (defined(my $info = shift @$order)) {
my ($mid, $ts, $u, $subj) = @$info;
my $n = delete $subjs->{$subj};
$mid = PublicInbox::Hval->new($mid)->as_href;
$subj = PublicInbox::Hval->new($subj)->as_html;
$u = PublicInbox::Hval->new($u)->as_html;
- $$dst .= "<a\nhref=\"t/$mid.html#u\"><b>$subj</b></a>\n- ";
+ $$dst .= "\n<a\nhref=\"t/$mid.html#u\"><b>$subj</b></a>\n- ";
$ts = POSIX::strftime('%Y-%m-%d %H:%M', gmtime($ts));
if ($n == 1) {
$$dst .= "created by $u @ $ts UTC\n"
--
EW
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 11/11] view: do not fold top-level messages in thread
2015-08-20 2:57 [PATCH 01/11] feed: remove threading from index Eric Wong
` (8 preceding siblings ...)
2015-08-20 2:57 ` [PATCH 10/11] index: layout fix + title and Atom feed links at top Eric Wong
@ 2015-08-20 2:57 ` Eric Wong
9 siblings, 0 replies; 11+ messages in thread
From: Eric Wong @ 2015-08-20 2:57 UTC (permalink / raw)
To: meta
This hopefully reduces clicking. We may drop folding entirely
since we can use Xapian to make searching easier.
---
lib/PublicInbox/View.pm | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/lib/PublicInbox/View.pm b/lib/PublicInbox/View.pm
index 391e3ad..17af21f 100644
--- a/lib/PublicInbox/View.pm
+++ b/lib/PublicInbox/View.pm
@@ -109,11 +109,15 @@ sub index_entry {
}
$rv .= "\n\n";
+ my ($fhref, $more_ref);
my $mhref = "${path}m/$href.html";
- my $fhref = "${path}f/$href.html";
+ if ($level > 0) {
+ $fhref = "${path}f/$href.html";
+ $more_ref = \$more;
+ }
# scan through all parts, looking for displayable text
$mime->walk_parts(sub {
- $rv .= index_walk($_[0], $enc_msg, $part_nr, $fhref, \$more);
+ $rv .= index_walk($_[0], $enc_msg, $part_nr, $fhref, $more_ref);
$part_nr++;
});
$mime->body_set('');
@@ -220,12 +224,14 @@ sub index_walk {
my $s = add_text_body($enc, $part, $part_nr, $fhref);
- # drop the remainder of git patches, they're usually better
- # to review when the full message is viewed
- $s =~ s!^---+\n.*\z!!ms and $$more = 'more...';
+ if ($more) {
+ # drop the remainder of git patches, they're usually better
+ # to review when the full message is viewed
+ $s =~ s!^---+\n.*\z!!ms and $$more = 'more...';
- # Drop signatures
- $s =~ s/^-- \n.*\z//ms and $$more = 'more...';
+ # Drop signatures
+ $s =~ s/^-- \n.*\z//ms and $$more = 'more...';
+ }
# kill any leading or trailing whitespace lines
$s =~ s/^\s*$//sgm;
--
EW
^ permalink raw reply related [flat|nested] 11+ messages in thread
end of thread, other threads:[~2015-08-20 2:57 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-08-20 2:57 [PATCH 01/11] feed: remove threading from index Eric Wong
2015-08-20 2:57 ` [PATCH 02/11] feed: move timestamp parsing to view Eric Wong
2015-08-20 2:57 ` [PATCH 03/11] use tables for rendering comment nesting Eric Wong
2015-08-20 2:57 ` [PATCH 04/11] view: avoid nesting <a> tags from auto-linkification Eric Wong
2015-08-20 2:57 ` [PATCH 05/11] index: simplify main landing page if search-enabled Eric Wong
2015-08-20 2:57 ` [PATCH 06/11] search: avoid needless decode Eric Wong
2015-08-20 2:57 ` [PATCH 07/11] search: reject ghosts in all cases Eric Wong
2015-08-20 2:57 ` [PATCH 08/11] view: reduce memory usage when displaying large threads Eric Wong
2015-08-20 2:57 ` [PATCH 09/11] search: bump schema version to 5 for subject_path Eric Wong
2015-08-20 2:57 ` [PATCH 10/11] index: layout fix + title and Atom feed links at top Eric Wong
2015-08-20 2:57 ` [PATCH 11/11] view: do not fold top-level messages in thread Eric Wong
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).