about summary refs log tree commit homepage
path: root/lib/PublicInbox/ManifestJsGz.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/PublicInbox/ManifestJsGz.pm')
-rw-r--r--lib/PublicInbox/ManifestJsGz.pm92
1 files changed, 37 insertions, 55 deletions
diff --git a/lib/PublicInbox/ManifestJsGz.pm b/lib/PublicInbox/ManifestJsGz.pm
index 328303ce..f98d9d01 100644
--- a/lib/PublicInbox/ManifestJsGz.pm
+++ b/lib/PublicInbox/ManifestJsGz.pm
@@ -1,8 +1,11 @@
 # 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
@@ -19,22 +22,12 @@ for my $mod (qw(JSON::MaybeXS JSON JSON::PP)) {
         $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 ($) {
@@ -53,7 +46,7 @@ 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) {
@@ -92,12 +85,12 @@ sub manifest_add ($$;$$) {
                         $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,
@@ -106,48 +99,37 @@ sub manifest_add ($$;$$) {
         };
 }
 
-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;