1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
| | # Copyright (C) all contributors <meta@public-inbox.org>
# License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
package PublicInbox::WwwTopics;
use v5.12;
use PublicInbox::Hval qw(ascii_html mid_href fmt_ts);
sub add_topic_html ($$) {
my (undef, $smsg) = @_;
my $s = ascii_html($smsg->{subject});
$s = '(no subject)' if $s eq '';
$_[0] .= "\n".fmt_ts($smsg->{ds}) .
qq{ <a\nhref="}.mid_href($smsg->{mid}).qq{/#r">$s</a>};
my $nr = $smsg->{'COUNT(num)'};
$_[0] .= " $nr+ messages" if $nr > 1;
}
# n.b. the `SELECT DISTINCT(tid)' subquery is critical for performance
# with giant inboxes and extindices
sub topics_new ($) {
$_[0]->do_get(<<EOS);
SELECT ds,ddd,COUNT(num) FROM over WHERE tid IN
(SELECT DISTINCT(tid) FROM over WHERE tid > 0 ORDER BY ts DESC LIMIT 200)
AND +num > 0
GROUP BY tid
ORDER BY ds ASC
EOS
}
sub topics_active ($) {
$_[0]->do_get(<<EOS);
SELECT ddd,MAX(ds) as ds,COUNT(num) FROM over WHERE tid IN
(SELECT DISTINCT(tid) FROM over WHERE tid > 0 ORDER BY ts DESC LIMIT 200)
AND +num > 0
GROUP BY tid
ORDER BY ds ASC
EOS
}
sub topics_i { pop @{$_[0]->{msgs}} }
sub topics_atom { # GET /$INBOX_NAME/topics_(new|active).atom
my ($ctx) = @_;
require PublicInbox::WwwAtomStream;
my ($hdr, $smsg, $val);
PublicInbox::WwwAtomStream->response($ctx, \&topics_i);
}
sub topics_html { # GET /$INBOX_NAME/topics_(new|active).html
my ($ctx) = @_;
require PublicInbox::WwwStream;
my $buf = '<pre>';
$ctx->{-html_more_links} = qq{\n- recent:[<a
href="./">subjects (threaded)</a>|};
if ($ctx->{topic_category} eq 'new') {
$ctx->{-html_more_links} .= qq{<b>topics (new)</b>|<a
href="./topics_active.html">topics (active)</a>]};
} else { # topic_category eq "active" - topics with recent replies
$ctx->{-html_more_links} .= qq{<a
href="./topics_new.html">topics (new)</a>|<b>topics (active)</b>]};
}
# can't use SQL to filter references since our schema wasn't designed
# for it, but our SQL sorts by ascending time to favor top-level
# messages while our final result (post-references filter) favors
# recent messages
my $msgs = delete $ctx->{msgs};
add_topic_html($buf, pop @$msgs) while scalar(@$msgs);
$buf .= '</pre>';
PublicInbox::WwwStream::html_oneshot($ctx, 200, $buf);
}
sub response {
my ($ctx, $ibx_name, $category, $type) = @_;
my ($ret, $over);
$ret = PublicInbox::WWW::invalid_inbox($ctx, $ibx_name) and return $ret;
$over = $ctx->{ibx}->over or
return PublicInbox::WWW::need($ctx, 'Overview', './');
$ctx->{msgs} = $category eq 'new' ? topics_new($over) :
topics_active($over);
$ctx->{topic_category} = $category;
$type eq 'atom' ? topics_atom($ctx) : topics_html($ctx);
}
1;
|