]> Sergey Matveev's repositories - public-inbox.git/blobdiff - lib/PublicInbox/Config.pm
Config.pm: Add support for mailing list information
[public-inbox.git] / lib / PublicInbox / Config.pm
index cdc939a60e59ecbb590d1ed72ff1f931e6d2ed42..c2fa40f970d6575306e02c93cdf0f148ffdcc89b 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2014-2018 all contributors <meta@public-inbox.org>
+# Copyright (C) 2014-2019 all contributors <meta@public-inbox.org>
 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
 #
 # Used throughout the project for reading configuration
@@ -25,6 +25,7 @@ sub new {
 
        # caches
        $self->{-by_addr} ||= {};
+       $self->{-by_list_id} ||= {};
        $self->{-by_name} ||= {};
        $self->{-by_newsgroup} ||= {};
        $self->{-no_obfuscate} ||= {};
@@ -60,8 +61,8 @@ sub new {
 sub lookup {
        my ($self, $recipient) = @_;
        my $addr = lc($recipient);
-       my $inbox = $self->{-by_addr}->{$addr};
-       return $inbox if $inbox;
+       my $ibx = $self->{-by_addr}->{$addr};
+       return $ibx if $ibx;
 
        my $pfx;
 
@@ -84,6 +85,33 @@ sub lookup {
        _fill($self, $pfx);
 }
 
+sub lookup_list_id {
+       my ($self, $list_id) = @_;
+       $list_id = lc($list_id);
+       my $ibx = $self->{-by_list_id}->{$list_id};
+       return $ibx if $ibx;
+
+       my $pfx;
+
+       foreach my $k (keys %$self) {
+               $k =~ /\A(publicinbox\.[\w-]+)\.listid\z/ or next;
+               my $v = $self->{$k};
+               if (ref($v) eq "ARRAY") {
+                       foreach my $alias (@$v) {
+                               (lc($alias) eq $list_id) or next;
+                               $pfx = $1;
+                               last;
+                       }
+               } else {
+                       (lc($v) eq $list_id) or next;
+                       $pfx = $1;
+                       last;
+               }
+       }
+       defined $pfx or return;
+       _fill($self, $pfx);
+}
+
 sub lookup_name ($$) {
        my ($self, $name) = @_;
        $self->{-by_name}->{$name} || _fill($self, "publicinbox.$name");
@@ -113,16 +141,16 @@ sub each_inbox {
 sub lookup_newsgroup {
        my ($self, $ng) = @_;
        $ng = lc($ng);
-       my $rv = $self->{-by_newsgroup}->{$ng};
-       return $rv if $rv;
+       my $ibx = $self->{-by_newsgroup}->{$ng};
+       return $ibx if $ibx;
 
        foreach my $k (keys %$self) {
                $k =~ m!\A(publicinbox\.[^/]+)\.newsgroup\z! or next;
                my $v = $self->{$k};
                my $pfx = $1;
                if ($v eq $ng) {
-                       $rv = _fill($self, $pfx);
-                       return $rv;
+                       $ibx = _fill($self, $pfx);
+                       return $ibx;
                }
        }
        undef;
@@ -151,14 +179,14 @@ sub git_config_dump {
        my ($file) = @_;
        my (%section_seen, @section_order);
        return {} unless -e $file;
-       my @cmd = (qw/git config/, "--file=$file", '-l');
+       my @cmd = (qw/git config -z -l/, "--file=$file");
        my $cmd = join(' ', @cmd);
        my $fh = popen_rd(\@cmd) or die "popen_rd failed for $file: $!\n";
        my %rv;
-       local $/ = "\n";
+       local $/ = "\0";
        while (defined(my $line = <$fh>)) {
                chomp $line;
-               my ($k, $v) = split(/=/, $line, 2);
+               my ($k, $v) = split(/\n/, $line, 2);
 
                my ($section) = ($k =~ /\A(\S+)\.[^\.]+\z/);
                unless (defined $section_seen{$section}) {
@@ -307,7 +335,7 @@ sub parse_cgitrc {
                        }
                } elsif (m!\Ainclude=(.+)\z!) {
                        parse_cgitrc($self, $1, $nesting + 1);
-               } elsif (m!\A(scan-hidden-path|remove-suffix)=(\d+)\z!) {
+               } elsif (m!\A(scan-hidden-path|remove-suffix)=([0-9]+)\z!) {
                        my ($k, $v) = ($1, $2);
                        $k =~ tr/-/_/;
                        $self->{"-cgit_$k"} = $v;
@@ -366,36 +394,45 @@ sub _fill_code_repo {
        $git;
 }
 
+sub _git_config_bool ($) {
+       my ($val) = @_;
+       if ($val =~ /\A(?:false|no|off|[\-\+]?(?:0x)?0+)\z/i) {
+               0;
+       } elsif ($val =~ /\A(?:true|yes|on|[\-\+]?(?:0x)?[0-9]+)\z/i) {
+               1;
+       } else {
+               undef;
+       }
+}
+
 sub _fill {
        my ($self, $pfx) = @_;
-       my $rv = {};
+       my $ibx = {};
 
        foreach my $k (qw(mainrepo filter url newsgroup
                        infourl watch watchheader httpbackendmax
                        replyto feedmax nntpserver indexlevel)) {
                my $v = $self->{"$pfx.$k"};
-               $rv->{$k} = $v if defined $v;
+               $ibx->{$k} = $v if defined $v;
        }
        foreach my $k (qw(obfuscate)) {
                my $v = $self->{"$pfx.$k"};
                defined $v or next;
-               if ($v =~ /\A(?:false|no|off|0)\z/) {
-                       $rv->{$k} = 0;
-               } elsif ($v =~ /\A(?:true|yes|on|1)\z/) {
-                       $rv->{$k} = 1;
+               if (defined(my $bval = _git_config_bool($v))) {
+                       $ibx->{$k} = $bval;
                } else {
                        warn "Ignoring $pfx.$k=$v in config, not boolean\n";
                }
        }
        # TODO: more arrays, we should support multi-value for
        # more things to encourage decentralization
-       foreach my $k (qw(address altid nntpmirror coderepo)) {
+       foreach my $k (qw(address altid nntpmirror coderepo hide listid)) {
                if (defined(my $v = $self->{"$pfx.$k"})) {
-                       $rv->{$k} = _array($v);
+                       $ibx->{$k} = _array($v);
                }
        }
 
-       return unless $rv->{mainrepo};
+       return unless $ibx->{mainrepo};
        my $name = $pfx;
        $name =~ s/\Apublicinbox\.//;
 
@@ -404,27 +441,32 @@ sub _fill {
                return;
        }
 
-       $rv->{name} = $name;
-       $rv->{-pi_config} = $self;
-       $rv = PublicInbox::Inbox->new($rv);
-       foreach (@{$rv->{address}}) {
+       $ibx->{name} = $name;
+       $ibx->{-pi_config} = $self;
+       $ibx = PublicInbox::Inbox->new($ibx);
+       foreach (@{$ibx->{address}}) {
                my $lc_addr = lc($_);
-               $self->{-by_addr}->{$lc_addr} = $rv;
+               $self->{-by_addr}->{$lc_addr} = $ibx;
                $self->{-no_obfuscate}->{$lc_addr} = 1;
        }
-       if (my $ng = $rv->{newsgroup}) {
-               $self->{-by_newsgroup}->{$ng} = $rv;
+       if (my $listids = $ibx->{listid}) {
+               foreach my $list_id (@$listids) {
+                       $self->{-by_list_id}->{$list_id} = $ibx;
+               }
+       }
+       if (my $ng = $ibx->{newsgroup}) {
+               $self->{-by_newsgroup}->{$ng} = $ibx;
        }
-       $self->{-by_name}->{$name} = $rv;
-       if ($rv->{obfuscate}) {
-               $rv->{-no_obfuscate} = $self->{-no_obfuscate};
-               $rv->{-no_obfuscate_re} = $self->{-no_obfuscate_re};
+       $self->{-by_name}->{$name} = $ibx;
+       if ($ibx->{obfuscate}) {
+               $ibx->{-no_obfuscate} = $self->{-no_obfuscate};
+               $ibx->{-no_obfuscate_re} = $self->{-no_obfuscate_re};
                each_inbox($self, sub {}); # noop to populate -no_obfuscate
        }
 
-       if (my $ibx_code_repos = $rv->{coderepo}) {
+       if (my $ibx_code_repos = $ibx->{coderepo}) {
                my $code_repos = $self->{-code_repos};
-               my $repo_objs = $rv->{-repo_objs} = [];
+               my $repo_objs = $ibx->{-repo_objs} = [];
                foreach my $nick (@$ibx_code_repos) {
                        my @parts = split(m!/!, $nick);
                        my $valid = 0;
@@ -437,7 +479,7 @@ sub _fill {
                }
        }
 
-       $rv
+       $ibx
 }
 
 1;