From f084e94a4774b95eb45f55fc9f0dfda678522e54 Mon Sep 17 00:00:00 2001
From: Eric Wong <e@80x24.org>
Date: Sat, 17 Dec 2016 04:27:52 +0000
Subject: [PATCH] feed: support publicinbox.<name>.feedmax

This allows users to customize by using smaller or larger Atom
feeds than the default value of 25 entries.
---
 Documentation/public-inbox-config.pod |  8 ++++++++
 lib/PublicInbox/Config.pm             |  3 ++-
 lib/PublicInbox/Feed.pm               |  5 +----
 lib/PublicInbox/Inbox.pm              | 11 +++++++++++
 t/config.t                            |  2 ++
 t/feed.t                              | 13 ++++---------
 6 files changed, 28 insertions(+), 14 deletions(-)

diff --git a/Documentation/public-inbox-config.pod b/Documentation/public-inbox-config.pod
index 00376457..cfd6c93d 100644
--- a/Documentation/public-inbox-config.pod
+++ b/Documentation/public-inbox-config.pod
@@ -120,6 +120,14 @@ addresses or mirrors.
 
 Default: none
 
+=item publicinbox.<name>.feedmax
+
+The size of an Atom feed for the inbox.  If specified more than
+once, only the last value is used.  Invalid values (<= 0) will
+be treated as the default value.
+
+Default: 25
+
 =back
 
 =head1 ENVIRONMENT
diff --git a/lib/PublicInbox/Config.pm b/lib/PublicInbox/Config.pm
index 8d66cf8c..6e31df72 100644
--- a/lib/PublicInbox/Config.pm
+++ b/lib/PublicInbox/Config.pm
@@ -145,7 +145,8 @@ sub _fill {
 	my $rv = {};
 
 	foreach my $k (qw(mainrepo address filter url newsgroup
-			infourl watch watchheader httpbackendmax)) {
+			infourl watch watchheader httpbackendmax
+			feedmax)) {
 		my $v = $self->{"$pfx.$k"};
 		$rv->{$k} = $v if defined $v;
 	}
diff --git a/lib/PublicInbox/Feed.pm b/lib/PublicInbox/Feed.pm
index 31d82adb..2a33fd29 100644
--- a/lib/PublicInbox/Feed.pm
+++ b/lib/PublicInbox/Feed.pm
@@ -8,9 +8,6 @@ use warnings;
 use Email::MIME;
 use PublicInbox::View;
 use PublicInbox::WwwAtomStream;
-use constant {
-	MAX_PER_PAGE => 25, # this needs to be tunable
-};
 
 # main function
 sub generate {
@@ -114,7 +111,7 @@ sub new_html_footer {
 
 sub each_recent_blob {
 	my ($ctx, $cb) = @_;
-	my $max = $ctx->{max} || MAX_PER_PAGE;
+	my $max = $ctx->{-inbox}->{feedmax};
 	my $hex = '[a-f0-9]';
 	my $addmsg = qr!^:000000 100644 \S+ \S+ A\t(${hex}{2}/${hex}{38})$!;
 	my $delmsg = qr!^:100644 000000 \S+ \S+ D\t(${hex}{2}/${hex}{38})$!;
diff --git a/lib/PublicInbox/Inbox.pm b/lib/PublicInbox/Inbox.pm
index 8c639082..5503980f 100644
--- a/lib/PublicInbox/Inbox.pm
+++ b/lib/PublicInbox/Inbox.pm
@@ -29,11 +29,22 @@ sub _weaken_later ($) {
 	$WEAKEN->{"$self"} = $self;
 }
 
+sub _set_uint ($$$) {
+	my ($opts, $field, $default) = @_;
+	my $val = $opts->{$field};
+	if (defined $val) {
+		$val = $val->[-1] if ref($val) eq 'ARRAY';
+		$val = undef if $val !~ /\A\d+\z/;
+	}
+	$opts->{$field} = $val || $default;
+}
+
 sub new {
 	my ($class, $opts) = @_;
 	my $v = $opts->{address} ||= 'public-inbox@example.com';
 	my $p = $opts->{-primary_address} = ref($v) eq 'ARRAY' ? $v->[0] : $v;
 	$opts->{domain} = ($p =~ /\@(\S+)\z/) ? $1 : 'localhost';
+	_set_uint($opts, 'feedmax', 25);
 	weaken($opts->{-pi_config});
 	bless $opts, $class;
 }
diff --git a/t/config.t b/t/config.t
index 073d1d03..4bbbc838 100644
--- a/t/config.t
+++ b/t/config.t
@@ -30,6 +30,7 @@ my $tmpdir = tempdir('pi-config-XXXXXX', TMPDIR => 1, CLEANUP => 1);
 		'url' => 'http://example.com/meta',
 		-primary_address => 'meta@public-inbox.org',
 		'name' => 'meta',
+		feedmax => 100,
 		-pi_config => $cfg,
 	}, "lookup matches expected output");
 
@@ -45,6 +46,7 @@ my $tmpdir = tempdir('pi-config-XXXXXX', TMPDIR => 1, CLEANUP => 1);
 		'mainrepo' => '/home/pi/test-main.git',
 		'domain' => 'public-inbox.org',
 		'name' => 'test',
+		feedmax => 100,
 		'url' => 'http://example.com/test',
 		-pi_config => $cfg,
 	}, "lookup matches expected output for test");
diff --git a/t/feed.t b/t/feed.t
index 19a9ba09..b60273ed 100644
--- a/t/feed.t
+++ b/t/feed.t
@@ -46,6 +46,7 @@ my $ibx = PublicInbox::Inbox->new({
 	name => 'testbox',
 	mainrepo => $git_dir,
 	url => 'http://example.com/test',
+	feedmax => 3,
 });
 my $git = $ibx->git;
 my $im = PublicInbox::Import->new($git, $ibx->{name}, 'test@example');
@@ -101,10 +102,7 @@ EOF
 {
 	# check initial feed
 	{
-		my $feed = string_feed({
-			-inbox => $ibx,
-			max => 3
-		});
+		my $feed = string_feed({ -inbox => $ibx });
 		SKIP: {
 			skip 'XML::Feed missing', 2 unless $have_xml_feed;
 			my $p = XML::Feed->parse(\$feed);
@@ -142,10 +140,7 @@ EOF
 
 	# check spam shows up
 	{
-		my $spammy_feed = string_feed({
-			-inbox => $ibx,
-			max => 3
-		});
+		my $spammy_feed = string_feed({ -inbox => $ibx });
 		SKIP: {
 			skip 'XML::Feed missing', 2 unless $have_xml_feed;
 			my $p = XML::Feed->parse(\$spammy_feed);
@@ -167,7 +162,7 @@ EOF
 
 	# spam no longer shows up
 	{
-		my $feed = string_feed({ -inbox => $ibx, max => 3 });
+		my $feed = string_feed({ -inbox => $ibx });
 		SKIP: {
 			skip 'XML::Feed missing', 2 unless $have_xml_feed;
 			my $p = XML::Feed->parse(\$feed);
-- 
2.50.0