diff options
author | Eric Wong <e@80x24.org> | 2021-08-28 11:50:06 +0000 |
---|---|---|
committer | Eric Wong <e@80x24.org> | 2021-08-30 22:44:12 +0000 |
commit | 5b96edcb1e0d825244d5a12470e0f32526262611 (patch) | |
tree | 815c273a564f6d3d53033f5cd8d9c01fd08dc372 /lib/PublicInbox | |
parent | b587bfbcbff710dc9667af85be6a2a619f918273 (diff) | |
download | public-inbox-5b96edcb1e0d825244d5a12470e0f32526262611.tar.gz |
This makes the mirroring and code retrieval instructions less obstructive. Relying on WwwText means we only use our Linkify module to make hrefs of full URLs; making relative and shortened hrefs off-limits; hopefully this isn't too much of a problem. coderepo information remains duplicated on every page since (IMHO) coderepos are an important feature; but nobody besides me has ever bothered to configure coderepos, so I suppose it's fine... Suggested-by: Konstantin Ryabitsev <konstantin@linuxfoundation.org> Link: https://public-inbox.org/meta/20210826132747.6gxuwnhftyf7c6hp@nitro.local/
Diffstat (limited to 'lib/PublicInbox')
-rw-r--r-- | lib/PublicInbox/WwwListing.pm | 4 | ||||
-rw-r--r-- | lib/PublicInbox/WwwStream.pm | 116 | ||||
-rw-r--r-- | lib/PublicInbox/WwwText.pm | 134 |
3 files changed, 140 insertions, 114 deletions
diff --git a/lib/PublicInbox/WwwListing.pm b/lib/PublicInbox/WwwListing.pm index ef9048b5..c3779619 100644 --- a/lib/PublicInbox/WwwListing.pm +++ b/lib/PublicInbox/WwwListing.pm @@ -226,9 +226,7 @@ sub psgi_triple { } else { $gzf->zmore('<pre>no inboxes, yet'); } - my $out = $gzf->zflush('</pre><hr><pre>'. - PublicInbox::WwwStream::code_footer($ctx->{env}) . - '</pre></body></html>'); + my $out = $gzf->zflush('</pre></body></html>'); $h->[3] = length($out); [ $code, $h, [ $out ] ]; } diff --git a/lib/PublicInbox/WwwStream.pm b/lib/PublicInbox/WwwStream.pm index d8142824..c960edc5 100644 --- a/lib/PublicInbox/WwwStream.pm +++ b/lib/PublicInbox/WwwStream.pm @@ -11,7 +11,6 @@ use v5.10.1; use parent qw(Exporter PublicInbox::GzipFilter); our @EXPORT_OK = qw(html_oneshot); use PublicInbox::Hval qw(ascii_html prurl ts2str); -our $TOR_URL = 'https://www.torproject.org/'; our $CODE_URL = [ qw( http://7fh6tueqddpjyxjmgtdiueylzoqt6pt7hec3pukyptlmohoowvhde4yd.onion/public-inbox.git @@ -42,8 +41,6 @@ sub html_top ($) { my $desc = ascii_html($ibx->description); my $title = delete($ctx->{-title_html}) // $desc; my $upfx = $ctx->{-upfx} || ''; - my $help = $upfx.'_/text/help/'; - my $color = $upfx.'_/text/color/'; my $atom = $ctx->{-atom} || $upfx.'new.atom'; my $top = "<b>$desc</b>"; if (my $t_max = $ctx->{-t_max}) { @@ -54,9 +51,11 @@ sub html_top ($) { $top = qq(<a\nhref="./">$top</a>); } my $code = $ibx->{coderepo} ? qq( / <a\nhref=#code>code</a>) : ''; - my $links = qq(<a\nhref="$help">help</a> / ). - qq(<a\nhref="$color">color</a> / ). - qq(<a\nhref=#mirror>mirror</a>$code / ). + # id=mirror must exist for legacy bookmarks + my $links = qq(<a\nhref="${upfx}_/text/help/">help</a> / ). + qq(<a\nhref="${upfx}_/text/color/">color</a> / ). + qq(<a\nid=mirror) . + qq(\nhref="${upfx}_/text/mirror/">mirror</a>$code / ). qq(<a\nhref="$atom">Atom feed</a>); if ($ibx->isrch) { my $q_val = delete($ctx->{-q_value_html}) // ''; @@ -106,109 +105,12 @@ EOF @ret; # may be empty, this sub is called as an arg for join() } -sub code_footer ($) { - my ($env) = @_; - my $u = prurl($env, $CODE_URL); - my $arg = $u; - if ($arg =~ s!\A(https?://)([^/\.]+)\.onion/!$1\$hostname\.onion/!i) { - "AGPL code for this site:\n\thostname=$2\n\t" . - qq(torsocks git clone <a\nhref="$u">$arg</a>) - } else { - qq(AGPL code for this site: git clone <a\nhref="$u">$u</a>) - } -} - sub _html_end { my ($ctx) = @_; - my $ibx = $ctx->{ibx}; - my $desc = ascii_html($ibx->description); - my $s = "<a\nid=mirror>"; - my $http = $ctx->{base_url}; - my $dir = (split(m!/!, $http))[-1]; - my %seen = ($http => 1); - if ($ibx->can('cloneurl')) { # PublicInbox::Inbox - $s .= "This inbox may be cloned and mirrored by anyone:</a>\n"; - my @urls; - my $max = $ibx->max_git_epoch; - # TODO: some of these URLs may be too long and we may need to - # do something like code_footer() above, but these are local - # admin-defined - if (defined($max)) { # v2 - for my $i (0..$max) { - # old epochs my be deleted: - -d "$ibx->{inboxdir}/git/$i.git" or next; - my $url = "$http/$i"; - $seen{$url} = 1; - push @urls, "$url $dir/git/$i.git"; - } - my $nr = scalar(@urls); - if ($nr > 1) { - $s .= "\n\t"; - $s .= "# this inbox consists of $nr epochs:"; - $urls[0] .= "\t# oldest"; - $urls[-1] .= "\t# newest"; - } - } else { # v1 - push @urls, $http; - } - # FIXME: epoch splits can be different in other repositories, - # use the "cloneurl" file as-is for now: - for my $u (@{$ibx->cloneurl}) { - next if $seen{$u}++; - push @urls, ($u =~ /\Ahttps?:/ ? - qq(<a\nhref="$u">$u</a>) : $u); - } - $s .= "\n"; - $s .= join('', map { "\tgit clone --mirror $_\n" } @urls); - if (my $addrs = $ibx->{address}) { - $addrs = join(' ', @$addrs) if ref($addrs) eq 'ARRAY'; - my $v = defined $max ? '-V2' : '-V1'; - $s .= <<EOF; - - # If you have public-inbox 1.1+ installed, you may - # initialize and index your mirror using the following commands: - public-inbox-init $v $ibx->{name} $dir/ $http \\ - $addrs - public-inbox-index $dir -EOF - } - } else { # PublicInbox::ExtSearch - $s .= <<EOM; -This is an extindex which is an amalgamation of several public-inboxes</a> -EOM - my $v = $ctx->{www}->{pi_cfg}->{lc('publicInbox.wwwListing')}; - if (($v // '') =~ /\A(?:all|match=domain)\z/) { - my $upfx = ($ctx->{-upfx} // ''). '../'; - $s .= <<EOM; -A list of them is available in the <a\nhref="$upfx">listing</a> -EOM - } - } - - my $cfg_link = ($ctx->{-upfx} // '').'_/text/config/raw'; - $s .= <<EOF; - -Example <a -href="$cfg_link">config snippet</a> for mirrors. -EOF - if ($ibx->can('nntp_url')) { - my @nntp = map { qq(<a\nhref="$_">$_</a>) } @{$ibx->nntp_url}; - if (@nntp) { - $s .= @nntp == 1 ? 'Newsgroup' : 'Newsgroups are'; - $s .= ' available over NNTP:'; - $s .= "\n\t" . join("\n\t", @nntp) . "\n"; - } - } - if ($s =~ m!\b[^:]+://\w+\.onion/!) { - $s .= " note: .onion URLs require Tor: "; - $s .= qq[<a\nhref="$TOR_URL">$TOR_URL</a>]; - } - '<hr><pre>'.join("\n\n", - $desc, - $s, - coderepos($ctx), - code_footer($ctx->{env}) - ).'</pre></body></html>'; + my @cr = coderepos($ctx); + scalar(@cr) ? + '<hr><pre>'.join("\n\n", @cr).'</pre></body></html>' : + '</body></html>'; } # callback for HTTP.pm (and any other PSGI servers) diff --git a/lib/PublicInbox/WwwText.pm b/lib/PublicInbox/WwwText.pm index 47310258..858fc2f7 100644 --- a/lib/PublicInbox/WwwText.pm +++ b/lib/PublicInbox/WwwText.pm @@ -7,7 +7,7 @@ use strict; use v5.10.1; use PublicInbox::Linkify; use PublicInbox::WwwStream; -use PublicInbox::Hval qw(ascii_html); +use PublicInbox::Hval qw(ascii_html prurl); use URI::Escape qw(uri_escape_utf8); use PublicInbox::GzipFilter qw(gzf_maybe); our $QP_URL = 'https://xapian.org/docs/queryparser.html'; @@ -23,7 +23,7 @@ sub get_text { my ($ctx, $key) = @_; my $code = 200; - $key = 'help' if !defined $key; # this 302s to _/text/help/ + $key //= 'help'; # this 302s to _/text/help/ # get the raw text the same way we get mboxrds my $raw = ($key =~ s!/raw\z!!); @@ -240,12 +240,138 @@ EOS 1; } +sub coderepos_raw ($$) { + my ($ctx, $top_url) = @_; + my $cr = $ctx->{ibx}->{coderepo} // return (); + my $cfg = $ctx->{www}->{pi_cfg}; + my @ret; + for my $cr_name (@$cr) { + $ret[0] //= <<EOF; +code repositories for project(s) associated with this inbox: +EOF + my $urls = $cfg->get_all("coderepo.$cr_name.cgiturl"); + if ($urls) { + for (@$urls) { + # relative or absolute URL?, prefix relative + # "foo.git" with appropriate number of "../" + my $u = m!\A(?:[a-z\+]+:)?//!i ? $_ : + $top_url.$_; + $ret[0] .= "\n\t" . prurl($ctx->{env}, $u); + } + } else { + $ret[0] .= qq[\n\t$cr_name.git (no URL configured)]; + } + } + @ret; # may be empty, this sub is called as an arg for join() +} + +sub _mirror_help ($$) { + my ($ctx, $txt) = @_; + my $ibx = $ctx->{ibx}; + my $base_url = $ibx->base_url($ctx->{env}); + chop $base_url; # no trailing slash for "git clone" + my $dir = (split(m!/!, $base_url))[-1]; + my %seen = ($base_url => 1); + my $top_url = $base_url; + $top_url =~ s!/[^/]+\z!/!; + $$txt .= "public-inbox mirroring instructions\n\n"; + if ($ibx->can('cloneurl')) { # PublicInbox::Inbox + $$txt .= "This inbox may be cloned and mirrored by anyone:\n"; + my @urls; + my $max = $ibx->max_git_epoch; + # TODO: some of these URLs may be too long and we may need to + # do something like code_footer() above, but these are local + # admin-defined + if (defined($max)) { # v2 + for my $i (0..$max) { + # old epochs my be deleted: + -d "$ibx->{inboxdir}/git/$i.git" or next; + my $url = "$base_url/$i"; + $seen{$url} = 1; + push @urls, "$url $dir/git/$i.git"; + } + my $nr = scalar(@urls); + if ($nr > 1) { + $$txt .= "\n\t"; + $$txt .= "# this inbox consists of $nr epochs:"; + $urls[0] .= " # oldest"; + $urls[-1] .= " # newest"; + } + } else { # v1 + push @urls, $base_url; + } + # FIXME: epoch splits can be different in other repositories, + # use the "cloneurl" file as-is for now: + for my $u (@{$ibx->cloneurl}) { + next if $seen{$u}++; + push @urls, $u; + } + $$txt .= "\n"; + $$txt .= join('', map { "\tgit clone --mirror $_\n" } @urls); + if (my $addrs = $ibx->{address}) { + $addrs = join(' ', @$addrs) if ref($addrs) eq 'ARRAY'; + my $v = defined $max ? '-V2' : '-V1'; + $$txt .= <<EOF; + + # If you have public-inbox 1.1+ installed, you may + # initialize and index your mirror using the following commands: + public-inbox-init $v $ibx->{name} $dir/ $base_url \\ + $addrs + public-inbox-index $dir +EOF + } + } else { # PublicInbox::ExtSearch + $$txt .= <<EOM; +This is an extindex which is an amalgamation of several public-inboxes. +Each public-inbox needs to be mirrored individually. +EOM + my $v = $ctx->{www}->{pi_cfg}->{lc('publicInbox.wwwListing')}; + if (($v // '') =~ /\A(?:all|match=domain)\z/) { + $$txt .= <<EOM; +A list of them is available at $top_url +EOM + } + } + my $cfg_link = "$base_url/_/text/config/raw"; + $$txt .= <<EOF; + +Example config snippet for mirrors: $cfg_link +EOF + if ($ibx->can('nntp_url')) { + my $nntp = $ibx->nntp_url; + if (scalar @$nntp) { + $$txt .= "\n"; + $$txt .= @$nntp == 1 ? 'Newsgroup' : 'Newsgroups are'; + $$txt .= ' available over NNTP:'; + $$txt .= "\n\t" . join("\n\t", @$nntp) . "\n"; + } + } + if ($$txt =~ m!\b[^:]+://\w+\.onion/!) { + $$txt .= <<EOM + +note: .onion URLs require Tor: https://www.torproject.org/ + +EOM + } + my $code_url = prurl($ctx->{env}, $PublicInbox::WwwStream::CODE_URL); + $$txt .= join("\n\n", + coderepos_raw($ctx, $top_url), # may be empty + "AGPL code for this site:\n\tgit clone $code_url"); + 1; +} + sub _default_text ($$$$) { my ($ctx, $key, $hdr, $txt) = @_; - return _colors_help($ctx, $txt) if $key eq 'color'; - $key eq 'config' and return $ctx->{ibx}->can('cloneurl') ? + if ($key eq 'mirror') { + return _mirror_help($ctx, $txt); + } elsif ($key eq 'color') { + return _colors_help($ctx, $txt); + } elsif ($key eq 'config') { + return $ctx->{ibx}->can('cloneurl') ? inbox_config($ctx, $hdr, $txt) : extindex_config($ctx, $hdr, $txt); + } + return if $key ne 'help'; # TODO more keys? my $ibx = $ctx->{ibx}; |