* RFE: Long .onion URL breaks mobile view
@ 2021-08-16 16:36 Konstantin Ryabitsev
2021-08-16 22:38 ` Eric Wong
2021-08-26 12:33 ` [PATCH 0/8] various WWW + extindex stuff Eric Wong
0 siblings, 2 replies; 21+ messages in thread
From: Konstantin Ryabitsev @ 2021-08-16 16:36 UTC (permalink / raw)
To: meta
Hello:
Passing more observations from people testing out x-lore.kernel.org:
- the long .onion URL at the bottom of each page causes problems on mobile
devices because it results in a very wide page with blank content on the
right side.
I suggest that we don't need to provide the "git clone" part, but merely add a
link to the git repository:
<a href="http://7fh....onion/public-inbox.git">AGPL code for this site</a>
This should still serve the same purpose and not result in rendering issues on
mobile devices.
-K
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: RFE: Long .onion URL breaks mobile view
2021-08-16 16:36 RFE: Long .onion URL breaks mobile view Konstantin Ryabitsev
@ 2021-08-16 22:38 ` Eric Wong
2021-08-16 22:53 ` Eric Wong
2021-08-26 12:33 ` [PATCH 0/8] various WWW + extindex stuff Eric Wong
1 sibling, 1 reply; 21+ messages in thread
From: Eric Wong @ 2021-08-16 22:38 UTC (permalink / raw)
To: Konstantin Ryabitsev; +Cc: meta
Konstantin Ryabitsev <konstantin@linuxfoundation.org> wrote:
> Hello:
>
> Passing more observations from people testing out x-lore.kernel.org:
>
> - the long .onion URL at the bottom of each page causes problems on mobile
> devices because it results in a very wide page with blank content on the
> right side.
Agreed, this is important feedback.
> I suggest that we don't need to provide the "git clone" part, but merely add a
> link to the git repository:
>
> <a href="http://7fh....onion/public-inbox.git">AGPL code for this site</a>
>
> This should still serve the same purpose and not result in rendering issues on
> mobile devices.
I think making it obvious a link goes to an external domain is
important. How about splitting it on long tokens? Something
like:
<a href="...">http://
7fh6tueqddpjyxjmgtdiueylzoqt6pt7hec3pukyptlmohoowvhde4yd
.onion/public-inbox.git</a>
Is a 56-character token OK for mobile displays? My own preference is to
wrap at 64-characters despite using 80-column displays.
I wish Tor could've figured out some better way to make .onion v3 URLs
shorter...
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: RFE: Long .onion URL breaks mobile view
2021-08-16 22:38 ` Eric Wong
@ 2021-08-16 22:53 ` Eric Wong
0 siblings, 0 replies; 21+ messages in thread
From: Eric Wong @ 2021-08-16 22:53 UTC (permalink / raw)
To: Konstantin Ryabitsev; +Cc: meta
Eric Wong <e@80x24.org> wrote:
> <a href="...">http://
> 7fh6tueqddpjyxjmgtdiueylzoqt6pt7hec3pukyptlmohoowvhde4yd
> .onion/public-inbox.git</a>
Actually, it's for "git clone" instructions, so something
shell-compatible might be required:
u=7fh6tueqddpjyxjmgtdiueylzoqt6pt7hec3pukyptlmohoowvhde4yd
torsocks git clone http://$u.onion/public-inbox.git
No good options, really :<
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 0/8] various WWW + extindex stuff
2021-08-16 16:36 RFE: Long .onion URL breaks mobile view Konstantin Ryabitsev
2021-08-16 22:38 ` Eric Wong
@ 2021-08-26 12:33 ` Eric Wong
2021-08-26 12:33 ` [PATCH 1/8] get rid of unnecessary bytes::length usage Eric Wong
` (8 more replies)
1 sibling, 9 replies; 21+ messages in thread
From: Eric Wong @ 2021-08-26 12:33 UTC (permalink / raw)
To: meta; +Cc: Konstantin Ryabitsev
This hopefully makes the long .onion URL more usable on small
displays; but I also got sidetracked into making our "use bytes"
stuff less scary based on the notice in the bytes(3perl)
manpage.
There's a couple of small extindex-related fixes to reconcile
the differences between the two ibxish object types for WWW.
Eric Wong (8):
get rid of unnecessary bytes::length usage
ds: use bytes::substr and bytes::length module-wide for now
www_stream: sh-friendly .onion URLs wrapping
www: avoid incorrect instructions for extindex
www_text: fix example config snippet for extindex
config: do not parse altid for extindex
www_text: add coderepo config support for extindex
move ->ids_after from mm to over
lib/PublicInbox/Config.pm | 2 +-
lib/PublicInbox/DS.pm | 21 +++---
lib/PublicInbox/ExtSearch.pm | 4 -
lib/PublicInbox/HTTP.pm | 17 ++---
lib/PublicInbox/ManifestJsGz.pm | 3 +-
lib/PublicInbox/Mbox.pm | 10 +--
lib/PublicInbox/Msgmap.pm | 11 ---
lib/PublicInbox/NNTP.pm | 4 +-
lib/PublicInbox/Over.pm | 11 +++
lib/PublicInbox/View.pm | 5 +-
lib/PublicInbox/ViewVCS.pm | 5 +-
lib/PublicInbox/WWW.pm | 10 +--
lib/PublicInbox/WwwAttach.pm | 4 +-
lib/PublicInbox/WwwHighlight.pm | 5 +-
lib/PublicInbox/WwwListing.pm | 4 +-
lib/PublicInbox/WwwStatic.pm | 4 +-
lib/PublicInbox/WwwStream.pm | 126 +++++++++++++++++++-------------
lib/PublicInbox/WwwText.pm | 103 ++++++++++++++++----------
t/extindex-psgi.t | 15 ++++
t/psgi_search.t | 1 -
t/search-thr-index.t | 8 +-
t/www_listing.t | 19 ++++-
xt/cmp-msgstr.t | 2 +-
23 files changed, 229 insertions(+), 165 deletions(-)
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 1/8] get rid of unnecessary bytes::length usage
2021-08-26 12:33 ` [PATCH 0/8] various WWW + extindex stuff Eric Wong
@ 2021-08-26 12:33 ` Eric Wong
2021-08-26 12:33 ` [PATCH 2/8] ds: use bytes::substr and bytes::length module-wide for now Eric Wong
` (7 subsequent siblings)
8 siblings, 0 replies; 21+ messages in thread
From: Eric Wong @ 2021-08-26 12:33 UTC (permalink / raw)
To: meta
The only place where we could return wide characters with -httpd
was the raw $INBOX_DIR/description text, which is now converted
to octets.
All daemon (HTTP/NNTP/IMAP) sockets are opened in binary mode,
so length() and bytes::length() are equivalent on reads. For
socket writes, any non-octet data would warn about wide characters
and we are strict in warnings with test_httpd.
All gzipped buffers are also octets, as is PublicInbox::Eml->body,
and anything from PerlIO objects ("git cat-file --batch" output,
filesystems), so bytes::length was unnecessary in all those places.
---
lib/PublicInbox/HTTP.pm | 17 ++++++++---------
lib/PublicInbox/ManifestJsGz.pm | 3 +--
lib/PublicInbox/NNTP.pm | 2 +-
lib/PublicInbox/View.pm | 5 ++---
lib/PublicInbox/ViewVCS.pm | 5 ++---
lib/PublicInbox/WWW.pm | 10 ++++------
lib/PublicInbox/WwwAttach.pm | 4 ++--
lib/PublicInbox/WwwHighlight.pm | 5 ++---
lib/PublicInbox/WwwListing.pm | 4 ++--
lib/PublicInbox/WwwStatic.pm | 4 ++--
lib/PublicInbox/WwwStream.pm | 4 ++--
lib/PublicInbox/WwwText.pm | 5 ++---
t/psgi_search.t | 1 -
t/search-thr-index.t | 8 ++++----
t/www_listing.t | 19 +++++++++++++++----
xt/cmp-msgstr.t | 2 +-
16 files changed, 50 insertions(+), 48 deletions(-)
diff --git a/lib/PublicInbox/HTTP.pm b/lib/PublicInbox/HTTP.pm
index d0708c5b..b2c74cf3 100644
--- a/lib/PublicInbox/HTTP.pm
+++ b/lib/PublicInbox/HTTP.pm
@@ -21,7 +21,6 @@
package PublicInbox::HTTP;
use strict;
use parent qw(PublicInbox::DS);
-use bytes (); # only for bytes::length
use Fcntl qw(:seek);
use Plack::HTTPParser qw(parse_http_request); # XS or pure Perl
use Plack::Util;
@@ -89,7 +88,7 @@ sub event_step { # called by PublicInbox::DS
return read_input($self) if ref($self->{env});
my $rbuf = $self->{rbuf} // (\(my $x = ''));
- $self->do_read($rbuf, 8192, bytes::length($$rbuf)) or return;
+ $self->do_read($rbuf, 8192, length($$rbuf)) or return;
rbuf_process($self, $rbuf);
}
@@ -104,7 +103,7 @@ sub rbuf_process {
# (they are rarely-used and git (as of 2.7.2) does not use them)
if ($r == -1 || $env{HTTP_TRAILER} ||
# this length-check is necessary for PURE_PERL=1:
- ($r == -2 && bytes::length($$rbuf) > 0x4000)) {
+ ($r == -2 && length($$rbuf) > 0x4000)) {
return quit($self, 400);
}
if ($r < 0) { # incomplete
@@ -121,7 +120,7 @@ sub rbuf_process {
# IO::Handle::write returns boolean, this returns bytes written:
sub xwrite ($$$) {
my ($fh, $rbuf, $max) = @_;
- my $w = bytes::length($$rbuf);
+ my $w = length($$rbuf);
$w = $max if $w > $max;
$fh->write($$rbuf, $w) or return;
$w;
@@ -236,7 +235,7 @@ sub response_header_write {
sub chunked_write ($$) {
my $self = $_[0];
return if $_[1] eq '';
- msg_more($self, sprintf("%x\r\n", bytes::length($_[1])));
+ msg_more($self, sprintf("%x\r\n", length($_[1])));
msg_more($self, $_[1]);
# use $self->write(\"\n\n") if you care about real-time
@@ -411,12 +410,12 @@ sub read_input_chunked { # unlikely...
$$rbuf =~ s/\A\r\n//s and
return app_dispatch($self, $input, $rbuf);
- return quit($self, 400) if bytes::length($$rbuf) > 2;
+ return quit($self, 400) if length($$rbuf) > 2;
}
if ($len == CHUNK_END) {
if ($$rbuf =~ s/\A\r\n//s) {
$len = CHUNK_START;
- } elsif (bytes::length($$rbuf) > 2) {
+ } elsif (length($$rbuf) > 2) {
return quit($self, 400);
}
}
@@ -426,14 +425,14 @@ sub read_input_chunked { # unlikely...
if (($len + -s $input) > $MAX_REQUEST_BUFFER) {
return quit($self, 413);
}
- } elsif (bytes::length($$rbuf) > CHUNK_MAX_HDR) {
+ } elsif (length($$rbuf) > CHUNK_MAX_HDR) {
return quit($self, 400);
}
# will break from loop since $len >= 0
}
if ($len < 0) { # chunk header is trickled, read more
- $self->do_read($rbuf, 8192, bytes::length($$rbuf)) or
+ $self->do_read($rbuf, 8192, length($$rbuf)) or
return recv_err($self, $len);
# (implicit) goto chunk_start if $r > 0;
}
diff --git a/lib/PublicInbox/ManifestJsGz.pm b/lib/PublicInbox/ManifestJsGz.pm
index 7fee78dd..69d81fa1 100644
--- a/lib/PublicInbox/ManifestJsGz.pm
+++ b/lib/PublicInbox/ManifestJsGz.pm
@@ -6,7 +6,6 @@ package PublicInbox::ManifestJsGz;
use strict;
use v5.10.1;
use parent qw(PublicInbox::WwwListing);
-use bytes (); # length
use PublicInbox::Config;
use IO::Compress::Gzip qw(gzip);
use HTTP::Date qw(time2str);
@@ -108,7 +107,7 @@ sub psgi_triple {
gzip(\$manifest => \(my $out));
[ 200, [ qw(Content-Type application/gzip),
'Last-Modified', time2str($ctx->{-mtime}),
- 'Content-Length', bytes::length($out) ], [ $out ] ]
+ 'Content-Length', length($out) ], [ $out ] ]
}
sub per_inbox {
diff --git a/lib/PublicInbox/NNTP.pm b/lib/PublicInbox/NNTP.pm
index 13a68bb8..aea04c05 100644
--- a/lib/PublicInbox/NNTP.pm
+++ b/lib/PublicInbox/NNTP.pm
@@ -241,7 +241,7 @@ sub parse_time ($$;$) {
$gmt = 1;
}
my ($YYYY, $MM, $DD);
- if (bytes::length($date) == 8) { # RFC 3977 allows YYYYMMDD
+ if (length($date) == 8) { # RFC 3977 allows YYYYMMDD
($YYYY, $MM, $DD) = unpack('A4A2A2', $date);
} else { # legacy clients send YYMMDD
my $YY;
diff --git a/lib/PublicInbox/View.pm b/lib/PublicInbox/View.pm
index 17d38302..94ea6148 100644
--- a/lib/PublicInbox/View.pm
+++ b/lib/PublicInbox/View.pm
@@ -5,8 +5,7 @@
# See Documentation/design_www.txt for this.
package PublicInbox::View;
use strict;
-use warnings;
-use bytes (); # only for bytes::length
+use v5.10.1;
use List::Util qw(max);
use PublicInbox::MsgTime qw(msg_datestamp);
use PublicInbox::Hval qw(ascii_html obfuscate_addrs prurl mid_href
@@ -531,7 +530,7 @@ sub attach_link ($$$$;$) {
return unless $part->{bdy};
my $nl = $idx eq '1' ? '' : "\n"; # like join("\n", ...)
- my $size = bytes::length($part->body);
+ my $size = length($part->body);
# hide attributes normally, unless we want to aid users in
# spotting MUA problems:
diff --git a/lib/PublicInbox/ViewVCS.pm b/lib/PublicInbox/ViewVCS.pm
index 702a075d..6365f045 100644
--- a/lib/PublicInbox/ViewVCS.pm
+++ b/lib/PublicInbox/ViewVCS.pm
@@ -15,8 +15,7 @@
package PublicInbox::ViewVCS;
use strict;
-use warnings;
-use bytes (); # only for bytes::length
+use v5.10.1;
use PublicInbox::SolverGit;
use PublicInbox::WwwStream qw(html_oneshot);
use PublicInbox::Linkify;
@@ -49,7 +48,7 @@ sub stream_blob_parse_hdr { # {parse_hdr} for Qspawn
} elsif (index($$bref, "\0") >= 0) {
[200, [qw(Content-Type application/octet-stream), @cl] ];
} else {
- my $n = bytes::length($$bref);
+ my $n = length($$bref);
if ($n >= $BIN_DETECT || $n == $size) {
return [200, [ 'Content-Type',
'text/plain; charset=UTF-8', @cl ] ];
diff --git a/lib/PublicInbox/WWW.pm b/lib/PublicInbox/WWW.pm
index 1afdece0..570e690e 100644
--- a/lib/PublicInbox/WWW.pm
+++ b/lib/PublicInbox/WWW.pm
@@ -11,10 +11,8 @@
# - Must not rely on static content
# - UTF-8 is only for user-content, 7-bit US-ASCII for us
package PublicInbox::WWW;
-use 5.010_001;
use strict;
-use warnings;
-use bytes (); # only for bytes::length
+use v5.10.1;
use PublicInbox::Config;
use PublicInbox::Hval;
use URI::Escape qw(uri_unescape);
@@ -646,8 +644,7 @@ sub get_css ($$$) {
$css = PublicInbox::UserContent::sample($ctx->{ibx}, $env);
}
defined $css or return r404();
- my $h = [ 'Content-Length', bytes::length($css),
- 'Content-Type', 'text/css' ];
+ my $h = [ 'Content-Length', length($css), 'Content-Type', 'text/css' ];
PublicInbox::GitHTTPBackend::cache_one_year($h);
[ 200, $h, [ $css ] ];
}
@@ -656,7 +653,8 @@ sub get_description {
my ($ctx, $inbox) = @_;
invalid_inbox($ctx, $inbox) || do {
my $d = $ctx->{ibx}->description . "\n";
- [ 200, [ 'Content-Length', bytes::length($d),
+ utf8::encode($d);
+ [ 200, [ 'Content-Length', length($d),
'Content-Type', 'text/plain' ], [ $d ] ];
};
}
diff --git a/lib/PublicInbox/WwwAttach.pm b/lib/PublicInbox/WwwAttach.pm
index a6c68a3f..c17394af 100644
--- a/lib/PublicInbox/WwwAttach.pm
+++ b/lib/PublicInbox/WwwAttach.pm
@@ -4,8 +4,8 @@
# For retrieving attachments from messages in the WWW interface
package PublicInbox::WwwAttach; # internal package
use strict;
+use v5.10.1;
use parent qw(PublicInbox::GzipFilter);
-use bytes (); # only for bytes::length
use PublicInbox::Eml;
sub referer_match ($) {
@@ -50,7 +50,7 @@ sub get_attach_i { # ->each_part callback
$part = "Deep-linking prevented\n";
}
}
- push @{$res->[1]}, 'Content-Length', bytes::length($part);
+ push @{$res->[1]}, 'Content-Length', length($part);
$res->[2]->[0] = $part;
}
diff --git a/lib/PublicInbox/WwwHighlight.pm b/lib/PublicInbox/WwwHighlight.pm
index 6fed2fed..3593c2d4 100644
--- a/lib/PublicInbox/WwwHighlight.pm
+++ b/lib/PublicInbox/WwwHighlight.pm
@@ -20,8 +20,7 @@
package PublicInbox::WwwHighlight;
use strict;
-use warnings;
-use bytes (); # only for bytes::length
+use v5.10.1;
use parent qw(PublicInbox::HlMod);
use PublicInbox::Linkify qw();
use PublicInbox::Hval qw(ascii_html);
@@ -69,7 +68,7 @@ sub call {
$l->linkify_2($$bref);
my $h = [ 'Content-Type', 'text/html; charset=UTF-8' ];
- push @$h, 'Content-Length', bytes::length($$bref);
+ push @$h, 'Content-Length', length($$bref);
[ 200, $h, [ $$bref ] ]
}
diff --git a/lib/PublicInbox/WwwListing.pm b/lib/PublicInbox/WwwListing.pm
index a31aa4ca..8b54d724 100644
--- a/lib/PublicInbox/WwwListing.pm
+++ b/lib/PublicInbox/WwwListing.pm
@@ -5,12 +5,12 @@
# Used by PublicInbox::WWW
package PublicInbox::WwwListing;
use strict;
+use v5.10.1;
use PublicInbox::Hval qw(prurl fmt_ts ascii_html);
use PublicInbox::Linkify;
use PublicInbox::GzipFilter qw(gzf_maybe);
use PublicInbox::ConfigIter;
use PublicInbox::WwwStream;
-use bytes (); # bytes::length
sub ibx_entry {
my ($ctx, $ibx, $ce) = @_;
@@ -213,7 +213,7 @@ sub psgi_triple {
my $out = $gzf->zflush('</pre><hr><pre>'.
PublicInbox::WwwStream::code_footer($ctx->{env}) .
'</pre></body></html>');
- $h->[3] = bytes::length($out);
+ $h->[3] = length($out);
[ $code, $h, [ $out ] ];
}
diff --git a/lib/PublicInbox/WwwStatic.pm b/lib/PublicInbox/WwwStatic.pm
index 29e4819d..b3476ab8 100644
--- a/lib/PublicInbox/WwwStatic.pm
+++ b/lib/PublicInbox/WwwStatic.pm
@@ -9,8 +9,8 @@
# functionality of nginx.
package PublicInbox::WwwStatic;
use strict;
+use v5.10.1;
use parent qw(Exporter);
-use bytes ();
use Fcntl qw(SEEK_SET O_RDONLY O_NONBLOCK);
use POSIX qw(strftime);
use HTTP::Date qw(time2str);
@@ -318,7 +318,7 @@ sub dir_response ($$$) {
"</head><body><pre>Index of $path_info_html</pre><hr><pre>\n");
$gzf->zmore(join("\n", @entries));
my $out = $gzf->zflush("</pre><hr></body></html>\n");
- $h->[3] = bytes::length($out);
+ $h->[3] = length($out);
[ 200, $h, [ $out ] ]
}
diff --git a/lib/PublicInbox/WwwStream.pm b/lib/PublicInbox/WwwStream.pm
index 2f8212d4..adcb5fe2 100644
--- a/lib/PublicInbox/WwwStream.pm
+++ b/lib/PublicInbox/WwwStream.pm
@@ -7,9 +7,9 @@
# See PublicInbox::GzipFilter parent class for more info.
package PublicInbox::WwwStream;
use strict;
+use v5.10.1;
use parent qw(Exporter PublicInbox::GzipFilter);
our @EXPORT_OK = qw(html_oneshot);
-use bytes (); # length
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
@@ -216,7 +216,7 @@ sub html_oneshot ($$;$) {
};
$ctx->zmore($$sref) if $sref;
my $bdy = $ctx->zflush(_html_end($ctx));
- $res_hdr->[3] = bytes::length($bdy);
+ $res_hdr->[3] = length($bdy);
[ $code, $res_hdr, [ $bdy ] ]
}
diff --git a/lib/PublicInbox/WwwText.pm b/lib/PublicInbox/WwwText.pm
index 76a95a6b..db5060ea 100644
--- a/lib/PublicInbox/WwwText.pm
+++ b/lib/PublicInbox/WwwText.pm
@@ -4,8 +4,7 @@
# used for displaying help texts and other non-mail content
package PublicInbox::WwwText;
use strict;
-use warnings;
-use bytes (); # only for bytes::length
+use v5.10.1;
use PublicInbox::Linkify;
use PublicInbox::WwwStream;
use PublicInbox::Hval qw(ascii_html);
@@ -43,7 +42,7 @@ sub get_text {
$txt = $gzf->translate($txt);
$txt .= $gzf->zflush;
}
- $hdr->[3] = bytes::length($txt);
+ $hdr->[3] = length($txt);
return [ $code, $hdr, [ $txt ] ]
}
diff --git a/t/psgi_search.t b/t/psgi_search.t
index 5bdd66ed..3da93eda 100644
--- a/t/psgi_search.t
+++ b/t/psgi_search.t
@@ -8,7 +8,6 @@ use IO::Uncompress::Gunzip qw(gunzip);
use PublicInbox::Eml;
use PublicInbox::Config;
use PublicInbox::Inbox;
-use bytes (); # only for bytes::length
my @mods = qw(DBD::SQLite Search::Xapian HTTP::Request::Common Plack::Test
URI::Escape Plack::Builder);
require_mods(@mods);
diff --git a/t/search-thr-index.t b/t/search-thr-index.t
index fc1b666a..62745dbc 100644
--- a/t/search-thr-index.t
+++ b/t/search-thr-index.t
@@ -1,8 +1,8 @@
+#!perl -w
# Copyright (C) 2017-2021 all contributors <meta@public-inbox.org>
# License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
use strict;
-use warnings;
-use bytes (); # only for bytes::length
+use v5.10.1;
use Test::More;
use PublicInbox::TestCommon;
use PublicInbox::MID qw(mids);
@@ -45,7 +45,7 @@ foreach (reverse split(/\n\n/, $data)) {
my $mime = PublicInbox::Eml->new(\$_);
$mime->header_set('From' => 'bw@g');
$mime->header_set('To' => 'git@vger.kernel.org');
- my $bytes = bytes::length($mime->as_string);
+ my $bytes = length($mime->as_string);
my $mid = mids($mime->header_obj)->[0];
my $smsg = bless {
bytes => $bytes,
@@ -92,7 +92,7 @@ To: git@vger.kernel.org
my $tid0 = $dbh->selectrow_array(<<'', undef, $num);
SELECT tid FROM over WHERE num = ? LIMIT 1
- my $bytes = bytes::length($mime->as_string);
+ my $bytes = length($mime->as_string);
my $mid = mids($mime->header_obj)->[0];
my $smsg = bless {
bytes => $bytes,
diff --git a/t/www_listing.t b/t/www_listing.t
index 6b3b408f..7ea12eea 100644
--- a/t/www_listing.t
+++ b/t/www_listing.t
@@ -55,7 +55,7 @@ sub tiny_test {
ok(my $clone = $manifest->{'/alt'}, '/alt in manifest');
is($clone->{owner}, "lorelei \x{100}", 'owner set');
is($clone->{reference}, '/bare', 'reference detected');
- is($clone->{description}, "we're all clones", 'description read');
+ is($clone->{description}, "we're \x{100}ll clones", 'description read');
ok(my $bare = $manifest->{'/bare'}, '/bare in manifest');
is($bare->{description}, 'Unnamed repository',
'missing $GIT_DIR/description fallback');
@@ -72,6 +72,10 @@ sub tiny_test {
ok(my $v2epoch1 = $manifest->{'/v2/git/1.git'}, 'v2 epoch 1 appeared');
like($v2epoch1->{description}, qr/ \[epoch 1\]\z/,
'epoch 1 in description');
+
+ $res = $http->get("http://$host:$port/alt/description");
+ is($res->{content}, "we're \xc4\x80ll clones\n", 'UTF-8 description')
+ or diag explain($res);
}
my $td;
@@ -91,9 +95,9 @@ SKIP: {
is(xsys(@clone, $alt, "$v2/git/$i.git"), 0, "clone epoch $i")
}
ok(open(my $fh, '>', "$v2/inbox.lock"), 'mock a v2 inbox');
- open $fh, '>', "$alt/description" or die;
- print $fh "we're all clones\n" or die;
- close $fh or die;
+ open $fh, '>', "$alt/description" or xbail "open $alt/description $!";
+ print $fh "we're \xc4\x80ll clones\n" or xbail "print $!";
+ close $fh or xbail "write: $alt/description $!";
is(xsys('git', "--git-dir=$alt", qw(config gitweb.owner),
"lorelei \xc4\x80"), 0,
'set gitweb user');
@@ -178,6 +182,13 @@ manifest = \${site}/v2/manifest.js.gz
for (qw(v2/git/0.git v2/git/1.git v2/git/2.git)) {
ok(-d "$tmpdir/per-inbox/$_", "grok-pull created $_");
}
+ $td->kill;
+ $td->join;
+ is($?, 0, 'no error in exited process');
+ open $fh, '<', $err or BAIL_OUT("open $err failed: $!");
+ my $eout = do { local $/; <$fh> };
+ unlike($eout, qr/wide/i, 'no Wide character warnings');
+ unlike($eout, qr/uninitialized/i, 'no uninitialized warnings');
}
done_testing();
diff --git a/xt/cmp-msgstr.t b/xt/cmp-msgstr.t
index e0e8ed5a..900127c7 100644
--- a/xt/cmp-msgstr.t
+++ b/xt/cmp-msgstr.t
@@ -60,7 +60,7 @@ my $cmp = sub {
my $dig = $dig_cls->new;
$dig->add($part);
push @$cmp_arg, "M: ".$dig->hexdigest;
- push @$cmp_arg, "B: ".bytes::length($part);
+ push @$cmp_arg, "B: ".length($part);
} else {
$part =~ s/\s+\z//s;
push @$cmp_arg, "X: ".$part;
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 2/8] ds: use bytes::substr and bytes::length module-wide for now
2021-08-26 12:33 ` [PATCH 0/8] various WWW + extindex stuff Eric Wong
2021-08-26 12:33 ` [PATCH 1/8] get rid of unnecessary bytes::length usage Eric Wong
@ 2021-08-26 12:33 ` Eric Wong
2021-08-26 12:33 ` [PATCH 3/8] www_stream: sh-friendly .onion URLs wrapping Eric Wong
` (6 subsequent siblings)
8 siblings, 0 replies; 21+ messages in thread
From: Eric Wong @ 2021-08-26 12:33 UTC (permalink / raw)
To: meta
The use of substr within IO::Handle->write may not be correct if
we have wide characters, so handle it ourselves.
bytes.pm usage is probably better fixed in PublicInbox::NNTP,
but the effort required is higher, so we'll just keep bytes in
DS for now.
---
lib/PublicInbox/DS.pm | 21 +++++++++++----------
1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/lib/PublicInbox/DS.pm b/lib/PublicInbox/DS.pm
index 7a4dfed0..d804792b 100644
--- a/lib/PublicInbox/DS.pm
+++ b/lib/PublicInbox/DS.pm
@@ -23,7 +23,7 @@ package PublicInbox::DS;
use strict;
use v5.10.1;
use parent qw(Exporter);
-use bytes;
+use bytes qw(length substr); # FIXME(?): needed for PublicInbox::NNTP
use POSIX qw(WNOHANG sigprocmask SIG_SETMASK);
use Fcntl qw(SEEK_SET :DEFAULT O_APPEND);
use Time::HiRes qw(clock_gettime CLOCK_MONOTONIC);
@@ -499,13 +499,14 @@ sub drop {
# n.b.: use ->write/->read for this buffer to allow compatibility with
# PerlIO::mmap or PerlIO::scalar if needed
sub tmpio ($$$) {
- my ($self, $bref, $off) = @_;
- my $fh = tmpfile('wbuf', $self->{sock}, O_APPEND) or
- return drop($self, "tmpfile $!");
- $fh->autoflush(1);
- my $len = bytes::length($$bref) - $off;
- $fh->write($$bref, $len, $off) or return drop($self, "write ($len): $!");
- [ $fh, 0 ] # [1] = offset, [2] = length, not set by us
+ my ($self, $bref, $off) = @_;
+ my $fh = tmpfile('wbuf', $self->{sock}, O_APPEND) or
+ return drop($self, "tmpfile $!");
+ $fh->autoflush(1);
+ my $len = length($$bref) - $off;
+ print $fh substr($$bref, $off, $len) or
+ return drop($self, "write ($len): $!");
+ [ $fh, 0 ] # [1] = offset, [2] = length, not set by us
}
=head2 C<< $obj->write( $data ) >>
@@ -547,7 +548,7 @@ sub write {
$bref->($self);
return 1;
} else {
- my $to_write = bytes::length($$bref);
+ my $to_write = length($$bref);
my $written = syswrite($sock, $$bref, $to_write);
if (defined $written) {
@@ -582,7 +583,7 @@ sub msg_more ($$) {
!$sock->can('stop_SSL')) {
my $n = send($sock, $_[1], MSG_MORE);
if (defined $n) {
- my $nlen = bytes::length($_[1]) - $n;
+ my $nlen = length($_[1]) - $n;
return 1 if $nlen == 0; # all done!
# queue up the unwritten substring:
my $tmpio = tmpio($self, \($_[1]), $n) or return 0;
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 3/8] www_stream: sh-friendly .onion URLs wrapping
2021-08-26 12:33 ` [PATCH 0/8] various WWW + extindex stuff Eric Wong
2021-08-26 12:33 ` [PATCH 1/8] get rid of unnecessary bytes::length usage Eric Wong
2021-08-26 12:33 ` [PATCH 2/8] ds: use bytes::substr and bytes::length module-wide for now Eric Wong
@ 2021-08-26 12:33 ` Eric Wong
2021-08-26 12:33 ` [PATCH 4/8] www: avoid incorrect instructions for extindex Eric Wong
` (5 subsequent siblings)
8 siblings, 0 replies; 21+ messages in thread
From: Eric Wong @ 2021-08-26 12:33 UTC (permalink / raw)
To: meta; +Cc: Konstantin Ryabitsev
The long v3 .onion URL was causing havoc on small mobile
displays, so extract "hostname" into a variable which can
still used as a Bourne shell snippet.
While we're at it, include "torsocks" in the git command used
for .onion URLs since that's the (near)-universal wrapper for
Tor-ifying things (like git) which are dynamically linked to
libc.
Cc: Konstantin Ryabitsev <konstantin@linuxfoundation.org>
Link: https://public-inbox.org/meta/20210816163654.c6gfzuezhji4l6s7@nitro.local/
---
lib/PublicInbox/WwwStream.pm | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/lib/PublicInbox/WwwStream.pm b/lib/PublicInbox/WwwStream.pm
index adcb5fe2..57c23690 100644
--- a/lib/PublicInbox/WwwStream.pm
+++ b/lib/PublicInbox/WwwStream.pm
@@ -12,8 +12,10 @@ 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
- https://public-inbox.org/public-inbox.git) ];
+
+our $CODE_URL = [ qw(
+http://7fh6tueqddpjyxjmgtdiueylzoqt6pt7hec3pukyptlmohoowvhde4yd.onion/public-inbox.git
+https://public-inbox.org/public-inbox.git) ];
sub base_url ($) {
my $ctx = shift;
@@ -107,7 +109,13 @@ EOF
sub code_footer ($) {
my ($env) = @_;
my $u = prurl($env, $CODE_URL);
- qq(AGPL code for this site: git clone <a\nhref="$u">$u</a>)
+ 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 {
@@ -125,6 +133,9 @@ EOF
my $max = $ibx->max_git_epoch;
my $dir = (split(m!/!, $http))[-1];
my %seen = ($http => 1);
+ # 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:
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 4/8] www: avoid incorrect instructions for extindex
2021-08-26 12:33 ` [PATCH 0/8] various WWW + extindex stuff Eric Wong
` (2 preceding siblings ...)
2021-08-26 12:33 ` [PATCH 3/8] www_stream: sh-friendly .onion URLs wrapping Eric Wong
@ 2021-08-26 12:33 ` Eric Wong
2021-08-26 12:33 ` [PATCH 5/8] www_text: fix example config snippet " Eric Wong
` (4 subsequent siblings)
8 siblings, 0 replies; 21+ messages in thread
From: Eric Wong @ 2021-08-26 12:33 UTC (permalink / raw)
To: meta
There's no way to clone an extindex, since there's no git
storage associated with them. So attempt to link to the
HTML listing of public-inboxes, instead.
---
lib/PublicInbox/ExtSearch.pm | 4 --
lib/PublicInbox/WwwStream.pm | 111 +++++++++++++++++++----------------
2 files changed, 62 insertions(+), 53 deletions(-)
diff --git a/lib/PublicInbox/ExtSearch.pm b/lib/PublicInbox/ExtSearch.pm
index 0b480c7e..bd301158 100644
--- a/lib/PublicInbox/ExtSearch.pm
+++ b/lib/PublicInbox/ExtSearch.pm
@@ -106,10 +106,6 @@ sub description {
'$EXTINDEX_DIR/description missing';
}
-sub cloneurl { [] } # TODO
-
-sub nntp_url { [] }
-
no warnings 'once';
*base_url = \&PublicInbox::Inbox::base_url;
*smsg_eml = \&PublicInbox::Inbox::smsg_eml;
diff --git a/lib/PublicInbox/WwwStream.pm b/lib/PublicInbox/WwwStream.pm
index 57c23690..d8142824 100644
--- a/lib/PublicInbox/WwwStream.pm
+++ b/lib/PublicInbox/WwwStream.pm
@@ -120,52 +120,50 @@ sub code_footer ($) {
sub _html_end {
my ($ctx) = @_;
- my $urls = <<EOF;
-<a
-id=mirror>This inbox may be cloned and mirrored by anyone:</a>
-EOF
-
my $ibx = $ctx->{ibx};
my $desc = ascii_html($ibx->description);
-
- my @urls;
+ my $s = "<a\nid=mirror>";
my $http = $ctx->{base_url};
- my $max = $ibx->max_git_epoch;
my $dir = (split(m!/!, $http))[-1];
my %seen = ($http => 1);
- # 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";
+ 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;
}
- my $nr = scalar(@urls);
- if ($nr > 1) {
- $urls .= "\n\t# this inbox consists of $nr epochs:";
- $urls[0] .= "\t# oldest";
- $urls[-1] .= "\t# newest";
+ # 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);
}
- } else { # v1
- push @urls, $http;
- }
-
- # FIXME: epoch splits can be different in other repositories,
- # use the "cloneurl" file as-is for now:
- foreach my $u (@{$ibx->cloneurl}) {
- next if $seen{$u}++;
- push @urls, $u =~ /\Ahttps?:/ ? qq(<a\nhref="$u">$u</a>) : $u;
- }
-
- $urls .= "\n" . 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';
- $urls .= <<EOF;
+ $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:
@@ -173,26 +171,41 @@ EOF
$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';
- $urls .= <<EOF;
+ $s .= <<EOF;
Example <a
href="$cfg_link">config snippet</a> for mirrors.
EOF
- my @nntp = map { qq(<a\nhref="$_">$_</a>) } @{$ibx->nntp_url};
- if (@nntp) {
- $urls .= @nntp == 1 ? 'Newsgroup' : 'Newsgroups are';
- $urls .= ' available over NNTP:';
- $urls .= "\n\t" . join("\n\t", @nntp) . "\n";
+ 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 ($urls =~ m!\b[^:]+://\w+\.onion/!) {
- $urls .= " note: .onion URLs require Tor: ";
- $urls .= qq[<a\nhref="$TOR_URL">$TOR_URL</a>];
+ 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,
- $urls,
+ $s,
coderepos($ctx),
code_footer($ctx->{env})
).'</pre></body></html>';
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 5/8] www_text: fix example config snippet for extindex
2021-08-26 12:33 ` [PATCH 0/8] various WWW + extindex stuff Eric Wong
` (3 preceding siblings ...)
2021-08-26 12:33 ` [PATCH 4/8] www: avoid incorrect instructions for extindex Eric Wong
@ 2021-08-26 12:33 ` Eric Wong
2021-08-26 12:33 ` [PATCH 6/8] config: do not parse altid " Eric Wong
` (3 subsequent siblings)
8 siblings, 0 replies; 21+ messages in thread
From: Eric Wong @ 2021-08-26 12:33 UTC (permalink / raw)
To: meta
extindex doesn't use the same config stuff as normal
"publicinbox" entries, so we'll need a separate function
for them.
---
lib/PublicInbox/WwwText.pm | 29 ++++++++++++++++++++++++++++-
t/extindex-psgi.t | 12 ++++++++++++
2 files changed, 40 insertions(+), 1 deletion(-)
diff --git a/lib/PublicInbox/WwwText.pm b/lib/PublicInbox/WwwText.pm
index db5060ea..eb5e3ac7 100644
--- a/lib/PublicInbox/WwwText.pm
+++ b/lib/PublicInbox/WwwText.pm
@@ -214,10 +214,37 @@ EOF
1;
}
+# n.b. this is a perfect candidate for memoization
+sub extindex_config ($$$) {
+ my ($ctx, $hdr, $txt) = @_;
+ my $ibx = $ctx->{ibx};
+ push @$hdr, 'Content-Disposition', 'inline; filename=extindex.config';
+ my $name = dq_escape($ibx->{name});
+ my $base_url = $ibx->base_url($ctx->{env});
+ $$txt .= <<EOS;
+; Example public-inbox config snippet for the external index (extindex) at:
+; $base_url
+; See public-inbox-config(5)manpage for more details:
+; https://public-inbox.org/public-inbox-config.html
+[extindex "$name"]
+ topdir = /path/to/extindex-topdir
+ url = https://example.com/$name/
+ url = http://example.onion/$name/
+EOS
+ for my $k (qw(infourl)) {
+ defined(my $v = $ibx->{$k}) or next;
+ $$txt .= "\t$k = $v\n";
+ }
+ # TODO: coderepo support for extindex
+ 1;
+}
+
sub _default_text ($$$$) {
my ($ctx, $key, $hdr, $txt) = @_;
return _colors_help($ctx, $txt) if $key eq 'color';
- return inbox_config($ctx, $hdr, $txt) if $key eq 'config';
+ $key eq 'config' and 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};
diff --git a/t/extindex-psgi.t b/t/extindex-psgi.t
index 6f62b5a0..b9acc979 100644
--- a/t/extindex-psgi.t
+++ b/t/extindex-psgi.t
@@ -40,6 +40,18 @@ my $client = sub {
'Host: header respected in Atom feed');
unlike($res->content, qr!http://bogus\.example\.com/!s,
'default URL ignored with different host header');
+
+ $res = $cb->(GET('/all/_/text/config/'));
+ is($res->code, 200, '/text/config HTML');
+ $res = $cb->(GET('/all/_/text/config/raw'));
+ is($res->code, 200, '/text/config raw');
+ my $f = "$tmpdir/extindex.config";
+ open my $fh, '>', $f or xbail $!;
+ print $fh $res->content or xbail $!;
+ close $fh or xbail $!;
+ my $cfg = PublicInbox::Config->git_config_dump($f);
+ is($?, 0, 'no errors from git-config parsing');
+ ok($cfg->{'extindex.all.topdir'}, 'extindex.topdir defined');
};
test_psgi(sub { $www->call(@_) }, $client);
%$env = (%$env, TMPDIR => $tmpdir, PI_CONFIG => $pi_config);
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 6/8] config: do not parse altid for extindex
2021-08-26 12:33 ` [PATCH 0/8] various WWW + extindex stuff Eric Wong
` (4 preceding siblings ...)
2021-08-26 12:33 ` [PATCH 5/8] www_text: fix example config snippet " Eric Wong
@ 2021-08-26 12:33 ` Eric Wong
2021-08-26 12:33 ` [PATCH 7/8] www_text: add coderepo config support " Eric Wong
` (2 subsequent siblings)
8 siblings, 0 replies; 21+ messages in thread
From: Eric Wong @ 2021-08-26 12:33 UTC (permalink / raw)
To: meta
There's currently no support for altid with extindex, and
there's likely no legacy precedent for using altid like there is
with single public-inboxes.
---
lib/PublicInbox/Config.pm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/PublicInbox/Config.pm b/lib/PublicInbox/Config.pm
index 7aa1f6c8..b3e00ae0 100644
--- a/lib/PublicInbox/Config.pm
+++ b/lib/PublicInbox/Config.pm
@@ -525,7 +525,7 @@ sub _fill_ei ($$) {
my $v = get_1($self, $pfx, $k) // next;
$es->{$k} = $v;
}
- for my $k (qw(altid coderepo hide url infourl)) {
+ for my $k (qw(coderepo hide url infourl)) {
my $v = $self->{"$pfx.$k"} // next;
$es->{$k} = _array($v);
}
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 7/8] www_text: add coderepo config support for extindex
2021-08-26 12:33 ` [PATCH 0/8] various WWW + extindex stuff Eric Wong
` (5 preceding siblings ...)
2021-08-26 12:33 ` [PATCH 6/8] config: do not parse altid " Eric Wong
@ 2021-08-26 12:33 ` Eric Wong
2021-08-26 12:33 ` [PATCH 8/8] move ->ids_after from mm to over Eric Wong
2021-08-26 13:27 ` [PATCH 0/8] various WWW + extindex stuff Konstantin Ryabitsev
8 siblings, 0 replies; 21+ messages in thread
From: Eric Wong @ 2021-08-26 12:33 UTC (permalink / raw)
To: meta
At least manually configured coderepos "just work"
for extindex, though it probably could be automatic
and inherited from the publicinbox configs.
---
lib/PublicInbox/WwwText.pm | 75 +++++++++++++++++++-------------------
1 file changed, 38 insertions(+), 37 deletions(-)
diff --git a/lib/PublicInbox/WwwText.pm b/lib/PublicInbox/WwwText.pm
index eb5e3ac7..47310258 100644
--- a/lib/PublicInbox/WwwText.pm
+++ b/lib/PublicInbox/WwwText.pm
@@ -129,7 +129,42 @@ sub dq_escape ($) {
$name;
}
-sub URI_PATH () { '^A-Za-z0-9\-\._~/' }
+sub _coderepo_config ($$) {
+ my ($ctx, $txt) = @_;
+ my $cr = $ctx->{ibx}->{coderepo} // return;
+ # note: this doesn't preserve cgitrc layout, since we parse cgitrc
+ # and drop the original structure
+ $$txt .= "\tcoderepo = $_\n" for @$cr;
+ $$txt .= <<'EOF';
+
+; `coderepo' entries allows blob reconstruction via patch emails if
+; the inbox is indexed with Xapian. `@@ <from-range> <to-range> @@'
+; line number ranges in `[PATCH]' emails link to /$INBOX_NAME/$OID/s/,
+; an HTTP endpoint which reconstructs git blobs via git-apply(1).
+EOF
+ my $pi_cfg = $ctx->{www}->{pi_cfg};
+ for my $cr_name (@$cr) {
+ my $urls = $pi_cfg->get_all("coderepo.$cr_name.cgiturl");
+ my $path = "/path/to/$cr_name";
+ $cr_name = dq_escape($cr_name);
+
+ $$txt .= qq([coderepo "$cr_name"]\n);
+ if ($urls && scalar(@$urls)) {
+ $$txt .= "\t; ";
+ $$txt .= join(" ||\n\t;\t", map {;
+ my $dst = $path;
+ if ($path !~ m![a-z0-9_/\.\-]!i) {
+ $dst = '"'.dq_escape($dst).'"';
+ }
+ qq(git clone $_ $dst);
+ } @$urls);
+ $$txt .= "\n";
+ }
+ $$txt .= "\tdir = $path\n";
+ $$txt .= "\tcgiturl = https://example.com/";
+ $$txt .= uri_escape_utf8($cr_name, '^A-Za-z0-9\-\._~/')."\n";
+ }
+}
# n.b. this is a perfect candidate for memoization
sub inbox_config ($$$) {
@@ -176,41 +211,7 @@ EOF
$$txt .= "\t$k = $v\n";
}
$$txt .= "\tnntpmirror = $_\n" for (@{$ibx->nntp_url});
-
- # note: this doesn't preserve cgitrc layout, since we parse cgitrc
- # and drop the original structure
- if (defined(my $cr = $ibx->{coderepo})) {
- $$txt .= "\tcoderepo = $_\n" for @$cr;
- $$txt .= <<'EOF';
-
-; `coderepo' entries allows blob reconstruction via patch emails if
-; the inbox is indexed with Xapian. `@@ <from-range> <to-range> @@'
-; line number ranges in `[PATCH]' emails link to /$INBOX_NAME/$OID/s/,
-; an HTTP endpoint which reconstructs git blobs via git-apply(1).
-EOF
- my $pi_cfg = $ctx->{www}->{pi_cfg};
- for my $cr_name (@$cr) {
- my $urls = $pi_cfg->get_all("coderepo.$cr_name.cgiturl");
- my $path = "/path/to/$cr_name";
- $cr_name = dq_escape($cr_name);
-
- $$txt .= qq([coderepo "$cr_name"]\n);
- if ($urls && scalar(@$urls)) {
- $$txt .= "\t; ";
- $$txt .= join(" ||\n\t;\t", map {;
- my $dst = $path;
- if ($path !~ m![a-z0-9_/\.\-]!i) {
- $dst = '"'.dq_escape($dst).'"';
- }
- qq(git clone $_ $dst);
- } @$urls);
- $$txt .= "\n";
- }
- $$txt .= "\tdir = $path\n";
- $$txt .= "\tcgiturl = https://example.com/";
- $$txt .= uri_escape_utf8($cr_name, URI_PATH)."\n";
- }
- }
+ _coderepo_config($ctx, $txt);
1;
}
@@ -235,7 +236,7 @@ EOS
defined(my $v = $ibx->{$k}) or next;
$$txt .= "\t$k = $v\n";
}
- # TODO: coderepo support for extindex
+ _coderepo_config($ctx, $txt);
1;
}
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 8/8] move ->ids_after from mm to over
2021-08-26 12:33 ` [PATCH 0/8] various WWW + extindex stuff Eric Wong
` (6 preceding siblings ...)
2021-08-26 12:33 ` [PATCH 7/8] www_text: add coderepo config support " Eric Wong
@ 2021-08-26 12:33 ` Eric Wong
2021-08-26 13:27 ` [PATCH 0/8] various WWW + extindex stuff Konstantin Ryabitsev
8 siblings, 0 replies; 21+ messages in thread
From: Eric Wong @ 2021-08-26 12:33 UTC (permalink / raw)
To: meta
Since we favor ->over in WWW and IMAP, move this method to
->over to reduce open files in common cases.
This fixes the /$EXTINDEX_NAME/all.mbox.gz endpoint for extindex
entries (which may get expensive...).
---
lib/PublicInbox/Mbox.pm | 10 ++++------
lib/PublicInbox/Msgmap.pm | 11 -----------
lib/PublicInbox/NNTP.pm | 2 +-
lib/PublicInbox/Over.pm | 11 +++++++++++
t/extindex-psgi.t | 3 +++
5 files changed, 19 insertions(+), 18 deletions(-)
diff --git a/lib/PublicInbox/Mbox.pm b/lib/PublicInbox/Mbox.pm
index 844099aa..f72af26b 100644
--- a/lib/PublicInbox/Mbox.pm
+++ b/lib/PublicInbox/Mbox.pm
@@ -161,19 +161,17 @@ sub all_ids_cb {
my $smsg = $ctx->{over}->get_art($num) or next;
return $smsg;
}
- $ctx->{ids} = $ids = $ctx->{mm}->ids_after(\($ctx->{prev}));
+ $ctx->{ids} = $ids = $ctx->{over}->ids_after(\($ctx->{prev}));
} while (@$ids);
}
sub mbox_all_ids {
my ($ctx) = @_;
- my $ibx = $ctx->{ibx};
my $prev = 0;
- my $mm = $ctx->{mm} = $ibx->mm;
- my $ids = $mm->ids_after(\$prev) or return
- [404, [qw(Content-Type text/plain)], ["No results found\n"]];
- $ctx->{over} = $ibx->over or
+ $ctx->{over} = $ctx->{ibx}->over or
return PublicInbox::WWW::need($ctx, 'Overview');
+ my $ids = $ctx->{over}->ids_after(\$prev) or return
+ [404, [qw(Content-Type text/plain)], ["No results found\n"]];
$ctx->{ids} = $ids;
$ctx->{prev} = $prev;
require PublicInbox::MboxGz;
diff --git a/lib/PublicInbox/Msgmap.pm b/lib/PublicInbox/Msgmap.pm
index 16a9a476..3887a9e6 100644
--- a/lib/PublicInbox/Msgmap.pm
+++ b/lib/PublicInbox/Msgmap.pm
@@ -189,17 +189,6 @@ CREATE TABLE IF NOT EXISTS meta (
}
-# used by NNTP.pm
-sub ids_after {
- my ($self, $num) = @_;
- my $ids = $self->{dbh}->selectcol_arrayref(<<'', undef, $$num);
-SELECT num FROM msgmap WHERE num > ?
-ORDER BY num ASC LIMIT 1000
-
- $$num = $ids->[-1] if @$ids;
- $ids;
-}
-
sub msg_range {
my ($self, $beg, $end, $cols) = @_;
$cols //= 'num,mid';
diff --git a/lib/PublicInbox/NNTP.pm b/lib/PublicInbox/NNTP.pm
index aea04c05..ea9ce183 100644
--- a/lib/PublicInbox/NNTP.pm
+++ b/lib/PublicInbox/NNTP.pm
@@ -210,7 +210,7 @@ sub listgroup_range_i {
sub listgroup_all_i {
my ($self, $num) = @_;
- my $ary = $self->{ibx}->mm(1)->ids_after($num);
+ my $ary = $self->{ibx}->over(1)->ids_after($num);
scalar(@$ary) or return;
more($self, join("\r\n", @$ary));
1;
diff --git a/lib/PublicInbox/Over.pm b/lib/PublicInbox/Over.pm
index 58fdea0e..19da056a 100644
--- a/lib/PublicInbox/Over.pm
+++ b/lib/PublicInbox/Over.pm
@@ -371,4 +371,15 @@ SELECT COUNT(*) FROM xref3 WHERE oidbin = ?
sub blob_exists { oidbin_exists($_[0], pack('H*', $_[1])) }
+# used by NNTP.pm
+sub ids_after {
+ my ($self, $num) = @_;
+ my $ids = dbh($self)->selectcol_arrayref(<<'', undef, $$num);
+SELECT num FROM over WHERE num > ?
+ORDER BY num ASC LIMIT 1000
+
+ $$num = $ids->[-1] if @$ids;
+ $ids;
+}
+
1;
diff --git a/t/extindex-psgi.t b/t/extindex-psgi.t
index b9acc979..d4761641 100644
--- a/t/extindex-psgi.t
+++ b/t/extindex-psgi.t
@@ -52,6 +52,9 @@ my $client = sub {
my $cfg = PublicInbox::Config->git_config_dump($f);
is($?, 0, 'no errors from git-config parsing');
ok($cfg->{'extindex.all.topdir'}, 'extindex.topdir defined');
+
+ $res = $cb->(GET('/all/all.mbox.gz'));
+ is($res->code, 200, 'all.mbox.gz');
};
test_psgi(sub { $www->call(@_) }, $client);
%$env = (%$env, TMPDIR => $tmpdir, PI_CONFIG => $pi_config);
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH 0/8] various WWW + extindex stuff
2021-08-26 12:33 ` [PATCH 0/8] various WWW + extindex stuff Eric Wong
` (7 preceding siblings ...)
2021-08-26 12:33 ` [PATCH 8/8] move ->ids_after from mm to over Eric Wong
@ 2021-08-26 13:27 ` Konstantin Ryabitsev
2021-08-28 11:50 ` [PATCH 0/2] www: split out mirror to /text/ Eric Wong
8 siblings, 1 reply; 21+ messages in thread
From: Konstantin Ryabitsev @ 2021-08-26 13:27 UTC (permalink / raw)
To: Eric Wong; +Cc: meta
On Thu, Aug 26, 2021 at 12:33:30PM +0000, Eric Wong wrote:
> This hopefully makes the long .onion URL more usable on small
> displays;
It's still not quite fixing the problem (actually, for some reason it's now
looking worse in the narrow mobile view for me). May I suggest the following:
- The / mirror / link at the top should link to _/text/mirror
- Everything below "This inbox may be clone and mirrored by anyone:" should
move to that page, including cloning instructions for public-inbox itself
- "AGPL code to this site" will be just a link to _/text/mirror/#clone
I think this solves multiple problems:
1. Removes the long link view from the thread listing, allowing for better
display on narrow screens; mobile device users are unlikely to be accessing
the mirroring instructions page, because that requires an actual
workstation to do.
2. On lists with a lot of epochs, moving mirroring instructions from every
view shrinks the page basement considerably (e.g. see /lkml/ with 11
epochs).
3. Allows adding more content to _/text/mirror page without any fear of
impacting the thread listing.
What do you think?
-K
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 0/2] www: split out mirror to /text/
2021-08-26 13:27 ` [PATCH 0/8] various WWW + extindex stuff Konstantin Ryabitsev
@ 2021-08-28 11:50 ` Eric Wong
2021-08-28 11:50 ` [PATCH 1/2] www: move mirror instructions " Eric Wong
` (2 more replies)
0 siblings, 3 replies; 21+ messages in thread
From: Eric Wong @ 2021-08-28 11:50 UTC (permalink / raw)
To: meta; +Cc: Konstantin Ryabitsev
Maybe this works better? *shrug*
I was somewhat under the impression every page needed to
link/advertise code under the AGPL, but maybe just one HTML page
is fine... We can't advertise our AGPL code to NNTP/IMAP users,
nor to people using Atom feed readers.
So maybe just burying the code link in the "mirror" link is
fine. I could never be comfortable with promoting anything I
do, anyways.
Eric Wong (2):
www: move mirror instructions to /text/
www_stream: description header links to top $INBOX_URL
lib/PublicInbox/WwwListing.pm | 4 +-
lib/PublicInbox/WwwStream.pm | 118 +++---------------------------
lib/PublicInbox/WwwText.pm | 134 +++++++++++++++++++++++++++++++++-
t/psgi_mount.t | 11 +--
4 files changed, 145 insertions(+), 122 deletions(-)
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 1/2] www: move mirror instructions to /text/
2021-08-28 11:50 ` [PATCH 0/2] www: split out mirror to /text/ Eric Wong
@ 2021-08-28 11:50 ` Eric Wong
2021-08-28 11:50 ` [PATCH 2/2] www_stream: description header links to top $INBOX_URL Eric Wong
2021-08-28 17:58 ` [PATCH 0/2] www: split out mirror to /text/ Konstantin Ryabitsev
2 siblings, 0 replies; 21+ messages in thread
From: Eric Wong @ 2021-08-28 11:50 UTC (permalink / raw)
To: meta; +Cc: Konstantin Ryabitsev
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/
---
lib/PublicInbox/WwwListing.pm | 4 +-
lib/PublicInbox/WwwStream.pm | 116 +++--------------------------
lib/PublicInbox/WwwText.pm | 134 +++++++++++++++++++++++++++++++++-
t/psgi_mount.t | 11 +--
4 files changed, 143 insertions(+), 122 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};
diff --git a/t/psgi_mount.t b/t/psgi_mount.t
index e9547c15..7c5487f3 100644
--- a/t/psgi_mount.t
+++ b/t/psgi_mount.t
@@ -48,14 +48,9 @@ test_psgi($app, sub {
unlike($res->content, qr!\b\Qhttp://[^/]+/test/\E!,
'No URLs which are not mount-aware');
- $res = $cb->(GET('/a/test/new.html'));
- like($res->content, qr!git clone --mirror http://[^/]+/a/test\b!,
- 'clone URL in new.html is mount-aware');
-
- $res = $cb->(GET('/a/test/blah%40example.com/'));
- is($res->code, 200, 'OK with URLMap mount');
- like($res->content, qr!git clone --mirror http://[^/]+/a/test\b!,
- 'clone URL in /$INBOX/$MESSAGE_ID/ is mount-aware');
+ $res = $cb->(GET('/a/test/_/text/mirror/'));
+ like($res->content, qr!git clone --mirror\s+.*?http://[^/]+/a/test\b!s,
+ 'clone URL in /text/mirror is mount-aware');
$res = $cb->(GET('/a/test/blah%40example.com/raw'));
is($res->code, 200, 'OK with URLMap mount');
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 2/2] www_stream: description header links to top $INBOX_URL
2021-08-28 11:50 ` [PATCH 0/2] www: split out mirror to /text/ Eric Wong
2021-08-28 11:50 ` [PATCH 1/2] www: move mirror instructions " Eric Wong
@ 2021-08-28 11:50 ` Eric Wong
2021-08-28 17:58 ` [PATCH 0/2] www: split out mirror to /text/ Konstantin Ryabitsev
2 siblings, 0 replies; 21+ messages in thread
From: Eric Wong @ 2021-08-28 11:50 UTC (permalink / raw)
To: meta
Making the inbox description link back to the most recent
per-inbox topics from text/ and $OID/s/ URLs seems useful,
rather than keeping the description up there.
Followup-to: 6c853f5256f3a324 ("www: improve navigation around contemporary threads")
---
lib/PublicInbox/WwwStream.pm | 2 ++
1 file changed, 2 insertions(+)
diff --git a/lib/PublicInbox/WwwStream.pm b/lib/PublicInbox/WwwStream.pm
index c960edc5..472316c2 100644
--- a/lib/PublicInbox/WwwStream.pm
+++ b/lib/PublicInbox/WwwStream.pm
@@ -49,6 +49,8 @@ sub html_top ($) {
# we had some kind of query, link to /$INBOX/?t=YYYYMMDDhhmmss
} elsif ($ctx->{qp}->{t}) {
$top = qq(<a\nhref="./">$top</a>);
+ } elsif (length($upfx)) {
+ $top = qq(<a\nhref="$upfx">$top</a>);
}
my $code = $ibx->{coderepo} ? qq( / <a\nhref=#code>code</a>) : '';
# id=mirror must exist for legacy bookmarks
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH 0/2] www: split out mirror to /text/
2021-08-28 11:50 ` [PATCH 0/2] www: split out mirror to /text/ Eric Wong
2021-08-28 11:50 ` [PATCH 1/2] www: move mirror instructions " Eric Wong
2021-08-28 11:50 ` [PATCH 2/2] www_stream: description header links to top $INBOX_URL Eric Wong
@ 2021-08-28 17:58 ` Konstantin Ryabitsev
2021-08-30 23:44 ` [PATCH 0/3] www: more footer and mirroring instructions tweaks Eric Wong
2 siblings, 1 reply; 21+ messages in thread
From: Konstantin Ryabitsev @ 2021-08-28 17:58 UTC (permalink / raw)
To: Eric Wong; +Cc: meta
On Sat, Aug 28, 2021 at 11:50:05AM +0000, Eric Wong wrote:
> Maybe this works better? *shrug*
>
> I was somewhat under the impression every page needed to
> link/advertise code under the AGPL, but maybe just one HTML page
> is fine... We can't advertise our AGPL code to NNTP/IMAP users,
> nor to people using Atom feed readers.
I think this looks great, Eric. You went a bit further than I suggested,
though -- I do think you should keep the following at each page bottom:
<hr>
<a href="../../_/text/mirror/">Get full contents and AGPL source for this site.</a>
Or some similar wording. I do think something like that belongs on each view
just to stress that everything about the site is fully available for
replication.
-K
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 0/3] www: more footer and mirroring instructions tweaks
2021-08-28 17:58 ` [PATCH 0/2] www: split out mirror to /text/ Konstantin Ryabitsev
@ 2021-08-30 23:44 ` Eric Wong
2021-08-30 23:44 ` [PATCH 1/3] www_stream: extra link to mirroring information in the footer Eric Wong
` (2 more replies)
0 siblings, 3 replies; 21+ messages in thread
From: Eric Wong @ 2021-08-30 23:44 UTC (permalink / raw)
To: meta; +Cc: Konstantin Ryabitsev
Some of the wording may still need tweaking, I'm preferring to
favor the data aspect over the code aspect of mirroring since
AGPL probably scares some people.
Not really sure about 3/3 or if including instructions to
grokmirror is out-of-scope for this project.
Eric Wong (3):
www_stream: extra link to mirroring information in the footer
www_text/mirror: spell out "external index" and "public inbox"
www_listing: add note about mirroring information
lib/PublicInbox/WwwListing.pm | 5 ++++-
lib/PublicInbox/WwwStream.pm | 24 +++++++++++++++++++-----
lib/PublicInbox/WwwText.pm | 15 ++++++++++-----
3 files changed, 33 insertions(+), 11 deletions(-)
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 1/3] www_stream: extra link to mirroring information in the footer
2021-08-30 23:44 ` [PATCH 0/3] www: more footer and mirroring instructions tweaks Eric Wong
@ 2021-08-30 23:44 ` Eric Wong
2021-08-30 23:44 ` [PATCH 2/3] www_text/mirror: spell out "external index" and "public inbox" Eric Wong
2021-08-30 23:44 ` [PATCH 3/3] www_listing: add note about mirroring information Eric Wong
2 siblings, 0 replies; 21+ messages in thread
From: Eric Wong @ 2021-08-30 23:44 UTC (permalink / raw)
To: meta; +Cc: Konstantin Ryabitsev
This may be redundant with the "mirror" link at the top right,
but maybe people will miss one. Properly capitalize the
"Code repositories" text while we're at it.
Link: https://public-inbox.org/20210828175827.rgzwqbn7brl56oej@nitro.local/
Cc: Konstantin Ryabitsev <konstantin@linuxfoundation.org>
---
lib/PublicInbox/WwwStream.pm | 24 +++++++++++++++++++-----
1 file changed, 19 insertions(+), 5 deletions(-)
diff --git a/lib/PublicInbox/WwwStream.pm b/lib/PublicInbox/WwwStream.pm
index 472316c2..a88ff972 100644
--- a/lib/PublicInbox/WwwStream.pm
+++ b/lib/PublicInbox/WwwStream.pm
@@ -89,7 +89,7 @@ sub coderepos ($) {
my @ret;
for my $cr_name (@$cr) {
$ret[0] //= <<EOF;
-<a id=code>code repositories for project(s) associated with this inbox:
+<a id=code>Code repositories for project(s) associated with this inbox:
EOF
my $urls = $cfg->get_all("coderepo.$cr_name.cgiturl");
if ($urls) {
@@ -109,10 +109,24 @@ EOF
sub _html_end {
my ($ctx) = @_;
- my @cr = coderepos($ctx);
- scalar(@cr) ?
- '<hr><pre>'.join("\n\n", @cr).'</pre></body></html>' :
- '</body></html>';
+ my $upfx = $ctx->{-upfx} || '';
+ my $m = "${upfx}_/text/mirror/";
+ my $x;
+ if ($ctx->{ibx}->can('cloneurl')) {
+ $x = <<EOF;
+This is a public inbox, see <a
+href="$m">mirroring instructions</a>
+on how to clone and mirror all data and code used for this inbox
+EOF
+ } else {
+ $x = <<EOF;
+This is an external index of several public inboxes,
+see <a href="$m">mirroring instructions</a> on how to clone and mirror
+all data and code used by this external index.
+EOF
+ }
+ chomp $x;
+ '<hr><pre>'.join("\n\n", coderepos($ctx), $x).'</pre></body></html>'
}
# callback for HTTP.pm (and any other PSGI servers)
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 2/3] www_text/mirror: spell out "external index" and "public inbox"
2021-08-30 23:44 ` [PATCH 0/3] www: more footer and mirroring instructions tweaks Eric Wong
2021-08-30 23:44 ` [PATCH 1/3] www_stream: extra link to mirroring information in the footer Eric Wong
@ 2021-08-30 23:44 ` Eric Wong
2021-08-30 23:44 ` [PATCH 3/3] www_listing: add note about mirroring information Eric Wong
2 siblings, 0 replies; 21+ messages in thread
From: Eric Wong @ 2021-08-30 23:44 UTC (permalink / raw)
To: meta
"extindex" and "public-inbox" are project-specific terms which
are probably unsuitable for folks who are seeing this for the
first time.
Use "public inbox" when referring to actual public inboxes,
since "public-inbox" is merely the name for this particular
implementation and others have adopted the same concept (IMHO
the concept is more important than any particular
implementation).
---
lib/PublicInbox/WwwText.pm | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/lib/PublicInbox/WwwText.pm b/lib/PublicInbox/WwwText.pm
index 858fc2f7..fabe39f6 100644
--- a/lib/PublicInbox/WwwText.pm
+++ b/lib/PublicInbox/WwwText.pm
@@ -246,9 +246,13 @@ sub coderepos_raw ($$) {
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:
+ $ret[0] //= do {
+ my $thing = $ctx->{ibx}->can('cloneurl') ?
+ 'public inbox' : 'external index';
+ <<EOF;
+Code repositories for project(s) associated with this $thing
EOF
+ };
my $urls = $cfg->get_all("coderepo.$cr_name.cgiturl");
if ($urls) {
for (@$urls) {
@@ -276,7 +280,8 @@ sub _mirror_help ($$) {
$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";
+ $$txt .=
+ "This public 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
@@ -322,8 +327,8 @@ 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.
+This is an external index 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/) {
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 3/3] www_listing: add note about mirroring information
2021-08-30 23:44 ` [PATCH 0/3] www: more footer and mirroring instructions tweaks Eric Wong
2021-08-30 23:44 ` [PATCH 1/3] www_stream: extra link to mirroring information in the footer Eric Wong
2021-08-30 23:44 ` [PATCH 2/3] www_text/mirror: spell out "external index" and "public inbox" Eric Wong
@ 2021-08-30 23:44 ` Eric Wong
2 siblings, 0 replies; 21+ messages in thread
From: Eric Wong @ 2021-08-30 23:44 UTC (permalink / raw)
To: meta
Perhaps this can be expanded to include grokmirror information
in the future. For now, just give a hint about the "mirror"
link for each inbox.
---
lib/PublicInbox/WwwListing.pm | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/lib/PublicInbox/WwwListing.pm b/lib/PublicInbox/WwwListing.pm
index c3779619..a9290802 100644
--- a/lib/PublicInbox/WwwListing.pm
+++ b/lib/PublicInbox/WwwListing.pm
@@ -226,7 +226,10 @@ sub psgi_triple {
} else {
$gzf->zmore('<pre>no inboxes, yet');
}
- my $out = $gzf->zflush('</pre></body></html>');
+ my $out = $gzf->zflush('</pre><hr><pre>'.
+qq(This is a listing of public inboxes, see the `mirror' link of each inbox
+for instructions on how to mirror all the data and code on this site.) .
+ '</pre></body></html>');
$h->[3] = length($out);
[ $code, $h, [ $out ] ];
}
^ permalink raw reply related [flat|nested] 21+ messages in thread
end of thread, other threads:[~2021-08-30 23:44 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-08-16 16:36 RFE: Long .onion URL breaks mobile view Konstantin Ryabitsev
2021-08-16 22:38 ` Eric Wong
2021-08-16 22:53 ` Eric Wong
2021-08-26 12:33 ` [PATCH 0/8] various WWW + extindex stuff Eric Wong
2021-08-26 12:33 ` [PATCH 1/8] get rid of unnecessary bytes::length usage Eric Wong
2021-08-26 12:33 ` [PATCH 2/8] ds: use bytes::substr and bytes::length module-wide for now Eric Wong
2021-08-26 12:33 ` [PATCH 3/8] www_stream: sh-friendly .onion URLs wrapping Eric Wong
2021-08-26 12:33 ` [PATCH 4/8] www: avoid incorrect instructions for extindex Eric Wong
2021-08-26 12:33 ` [PATCH 5/8] www_text: fix example config snippet " Eric Wong
2021-08-26 12:33 ` [PATCH 6/8] config: do not parse altid " Eric Wong
2021-08-26 12:33 ` [PATCH 7/8] www_text: add coderepo config support " Eric Wong
2021-08-26 12:33 ` [PATCH 8/8] move ->ids_after from mm to over Eric Wong
2021-08-26 13:27 ` [PATCH 0/8] various WWW + extindex stuff Konstantin Ryabitsev
2021-08-28 11:50 ` [PATCH 0/2] www: split out mirror to /text/ Eric Wong
2021-08-28 11:50 ` [PATCH 1/2] www: move mirror instructions " Eric Wong
2021-08-28 11:50 ` [PATCH 2/2] www_stream: description header links to top $INBOX_URL Eric Wong
2021-08-28 17:58 ` [PATCH 0/2] www: split out mirror to /text/ Konstantin Ryabitsev
2021-08-30 23:44 ` [PATCH 0/3] www: more footer and mirroring instructions tweaks Eric Wong
2021-08-30 23:44 ` [PATCH 1/3] www_stream: extra link to mirroring information in the footer Eric Wong
2021-08-30 23:44 ` [PATCH 2/3] www_text/mirror: spell out "external index" and "public inbox" Eric Wong
2021-08-30 23:44 ` [PATCH 3/3] www_listing: add note about mirroring information 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).