# Copyright (C) 2020 all contributors <meta@public-inbox.org>
# License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
+
+# generates manifest.js.gz for grokmirror(1)
package PublicInbox::ManifestJsGz;
use strict;
use v5.10.1;
+use parent qw(PublicInbox::WwwListing);
use Digest::SHA ();
use File::Spec ();
use bytes (); # length
$json = $mod->new->ascii(1) and last;
}
-sub response {
- my ($env, $list) = @_;
- $json or return [ 404, [], [] ];
- my $self = bless {
- -abs2urlpath => {},
- -mtime => 0,
- manifest => {},
- -list => $list,
- psgi_env => $env,
- }, __PACKAGE__;
-
- # PSGI server will call this immediately and give us a callback (-wcb)
- sub {
- $self->{-wcb} = $_[0]; # HTTP write callback
- iterate_start($self);
- };
+# called by WwwListing
+sub url_regexp {
+ my ($ctx) = @_;
+ # grokmirror uses relative paths, so it's domain-dependent
+ # SUPER calls PublicInbox::WwwListing::url_regexp
+ $ctx->SUPER::url_regexp('publicInbox.grokManifest', 'match=domain');
}
sub fingerprint ($) {
}
sub manifest_add ($$;$$) {
- my ($self, $ibx, $epoch, $default_desc) = @_;
+ my ($ctx, $ibx, $epoch, $default_desc) = @_;
my $url_path = "/$ibx->{name}";
my $git_dir = $ibx->{inboxdir};
if (defined $epoch) {
$reference =~ s!/[^/]+/?\z!!; # basename
}
}
- $self->{-abs2urlpath}->{$git_dir} = $url_path;
+ $ctx->{-abs2urlpath}->{$git_dir} = $url_path;
my $modified = $git->modified;
- if ($modified > $self->{-mtime}) {
- $self->{-mtime} = $modified;
+ if ($modified > ($ctx->{-mtime} // 0)) {
+ $ctx->{-mtime} = $modified;
}
- $self->{manifest}->{$url_path} = {
+ $ctx->{manifest}->{$url_path} = {
owner => $owner,
reference => $reference,
description => $desc,
};
}
-sub iterate_start {
- my ($self) = @_;
- if (my $async = $self->{psgi_env}->{'pi-httpd.async'}) {
- # PublicInbox::HTTPD::Async->new
- $async->(undef, undef, $self);
- } else {
- event_step($self) while $self->{-wcb};
- }
-}
-
-sub event_step {
- my ($self) = @_;
- while (my $ibx = shift(@{$self->{-list}})) {
- eval {
- if (defined(my $max = $ibx->max_git_epoch)) {
- my $desc = $ibx->description;
- for my $epoch (0..$max) {
- manifest_add($self, $ibx, $epoch, $desc)
- }
- } else {
- manifest_add($self, $ibx);
+sub ibx_entry {
+ my ($ctx, $ibx) = @_;
+ eval {
+ if (defined(my $max = $ibx->max_git_epoch)) {
+ my $desc = $ibx->description;
+ for my $epoch (0..$max) {
+ manifest_add($ctx, $ibx, $epoch, $desc);
}
- };
- warn "E: $@" if $@;
- if (my $async = $self->{psgi_env}->{'pi-httpd.async'}) {
- # PublicInbox::HTTPD::Async->new
- $async->(undef, undef, $self);
+ } else {
+ manifest_add($ctx, $ibx);
}
- return; # more steps needed
- }
- my $abs2urlpath = delete $self->{-abs2urlpath};
- my $wcb = delete $self->{-wcb};
- my $manifest = delete $self->{manifest};
+ };
+ warn "E: $@" if $@;
+}
+
+sub hide_key { 'manifest' }
+
+# overrides WwwListing->psgi_triple
+sub psgi_triple {
+ my ($ctx) = @_;
+ my $abs2urlpath = delete($ctx->{-abs2urlpath}) // {};
+ my $manifest = delete($ctx->{manifest}) // {};
while (my ($url_path, $repo) = each %$manifest) {
defined(my $abs = $repo->{reference}) or next;
$repo->{reference} = $abs2urlpath->{$abs};
}
$manifest = $json->encode($manifest);
gzip(\$manifest => \(my $out));
- $wcb->([ 200, [ qw(Content-Type application/gzip),
- 'Last-Modified', time2str($self->{-mtime}),
- 'Content-Length', bytes::length($out) ], [ $out ] ]);
+ [ 200, [ qw(Content-Type application/gzip),
+ 'Last-Modified', time2str($ctx->{-mtime}),
+ 'Content-Length', bytes::length($out) ], [ $out ] ]
}
1;