1 # Copyright (C) 2016 all contributors <meta@public-inbox.org>
2 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
4 # serves the /$INBOX/_/* endpoints from :text/* of the git tree
5 package PublicInbox::WwwText;
8 use PublicInbox::Linkify;
9 use PublicInbox::WwwStream;
10 use PublicInbox::Hval qw(ascii_html);
11 our $QP_URL = 'https://xapian.org/docs/queryparser.html';
12 our $WIKI_URL = 'https://en.wikipedia.org/wiki';
14 # /$INBOX/_/text/$KEY/ # KEY may contain slashes
15 # For now, "help" is the only supported $KEY
20 $key = 'help' if !defined $key; # this 302s to _/text/help/
22 # get the raw text the same way we get mboxrds
23 my $raw = ($key =~ s!/raw\z!!);
24 my $have_tslash = ($key =~ s!/\z!!) if !$raw;
27 if (!_default_text($ctx, $key, \$txt)) {
29 $txt = "404 Not Found ($key)\n";
32 return [ $code, [ 'Content-Type', 'text/plain',
33 'Content-Length', bytes::length($txt) ],
37 # enforce trailing slash for "wget -r" compatibility
38 if (!$have_tslash && $code == 200) {
39 my $url = $ctx->{-inbox}->base_url($ctx->{env});
40 $url .= "_/text/$key/";
42 return [ 302, [ 'Content-Type', 'text/plain',
44 [ "Redirecting to $url\n" ] ];
47 # Follow git commit message conventions,
48 # first line is the Subject/title
49 my ($title) = ($txt =~ /\A([^\n]*)/s);
51 $ctx->{-title_html} = ascii_html($title);
53 my $nslash = ($key =~ tr!/!/!);
54 $ctx->{-upfx} = '../../../' . ('../' x $nslash);
56 PublicInbox::WwwStream->response($ctx, $code, sub {
58 $nr == 1 ? '<pre>'.$txt.'</pre>' : undef
63 my $l = PublicInbox::Linkify->new;
64 $_[0] = $l->linkify_2(ascii_html($l->linkify_1($_[0])));
67 sub _srch_prefix ($$) {
68 my ($srch, $txt) = @_;
71 my $help = $srch->help;
73 for ($i = 0; $i < @$help; $i += 2) {
74 my $pfx = $help->[$i];
76 $pad = $n if $n > $pad;
78 $htxt .= $help->[$i + 1];
82 my $padding = ' ' x ($pad + 8);
83 $htxt =~ s/^/$padding/gms;
84 $htxt =~ s/^$padding(\S+)\0/" $1".
85 (' ' x ($pad - length($1)))/egms;
86 $htxt =~ s/\f\n/\n/gs;
92 sub _default_text ($$$) {
93 my ($ctx, $key, $txt) = @_;
94 return if $key ne 'help'; # TODO more keys?
96 my $ibx = $ctx->{-inbox};
97 my $base_url = $ibx->base_url($ctx->{env});
98 $$txt .= "public-inbox help for $base_url\n";
104 public-inbox uses Message-ID identifiers in URLs.
105 One may look up messages by substituting Message-IDs
106 (without the leading '<' or trailing '>') into the URL.
107 Forward slash ('/') characters in the Message-IDs
108 need to be escaped as "%2F" (without quotes).
110 Thus, it is possible to retrieve any message by its
111 Message-ID by going to:
113 $base_url<Message-ID>/
115 (without the '<' or '>')
117 Message-IDs are described at:
123 # n.b. we use the Xapian DB for any regeneratable,
124 # order-of-arrival-independent data.
125 my $srch = $ibx->search;
131 This public-inbox has search functionality provided by Xapian.
133 It supports typical AND, OR, NOT, '+', '-' queries present
134 in other search engines.
136 We also support search prefixes to limit the scope of the
137 search to certain fields using prefixes.
139 Prefixes supported in this installation include:
142 _srch_prefix($srch, $txt);
145 The upstream Xapian query parser documentation fully explains
153 Message threading is enabled for this public-inbox,
154 additional endpoints for message threads are available:
156 * $base_url<Message-ID>/T/#u
158 Loads the thread belonging to the given <Message-ID>
159 in flat chronological order. The "#u" anchor
160 focuses the browser on the given <Message-ID>.
162 * $base_url<Message-ID>/t/#u
164 Loads the thread belonging to the given <Message-ID>
165 in threaded order with nesting. For deep threads,
166 this requires a wide display or horizontal scrolling.
168 Both of these HTML endpoints are suitable for offline reading
169 using the thread overview at the bottom of each page.
171 Users of feed readers may follow a particular thread using:
173 * $base_url<Message-ID>/t.atom
175 Which loads the thread in Atom Syndication Standard
176 described at Wikipedia and RFC4287:
178 $WIKI_URL/Atom_(standard)
179 https://tools.ietf.org/html/rfc4287
181 Finally, the gzipped mbox for a thread is available for
182 downloading and importing into your favorite mail client:
184 * $base_url<Message-ID>/t.mbox.gz
186 We use the mboxrd variant of the mbox format described
194 This help text is maintained by public-inbox developers
195 reachable via plain-text email at: meta\@public-inbox.org
198 # TODO: support admin contact info in ~/.public-inbox/config