]> Sergey Matveev's repositories - public-inbox.git/blob - lib/PublicInbox/NewsGroup.pm
3a3189584af438f8036f6e1f9353a90898f4c685
[public-inbox.git] / lib / PublicInbox / NewsGroup.pm
1 # Copyright (C) 2015 all contributors <meta@public-inbox.org>
2 # License: AGPLv3 or later (https://www.gnu.org/licenses/agpl-3.0.txt)
3 #
4 # Used only by the NNTP server to represent a public-inbox git repository
5 # as a newsgroup
6 package PublicInbox::NewsGroup;
7 use strict;
8 use warnings;
9 use Scalar::Util qw(weaken);
10 require Danga::Socket;
11 require PublicInbox::Msgmap;
12 require PublicInbox::Search;
13 require PublicInbox::GitCatFile;
14
15 sub new {
16         my ($class, $name, $git_dir, $address) = @_;
17         $address = $address->[0] if ref($address);
18         my $self = bless {
19                 name => $name,
20                 git_dir => $git_dir,
21                 address => $address,
22         }, $class;
23         $self->{domain} = ($address =~ /\@(\S+)\z/) ? $1 : 'localhost';
24         $self;
25 }
26
27 sub defer_weaken {
28         my ($self, $field) = @_;
29         Danga::Socket->AddTimer(30, sub { weaken($self->{$field}) });
30 }
31
32 sub gcf {
33         my ($self) = @_;
34         $self->{gcf} ||= eval {
35                 my $gcf = PublicInbox::GitCatFile->new($self->{git_dir});
36
37                 # git repos may be repacked and old packs unlinked
38                 defer_weaken($self, 'gcf');
39                 $gcf;
40         };
41 }
42
43 sub usable {
44         my ($self) = @_;
45         eval {
46                 PublicInbox::Msgmap->new($self->{git_dir});
47                 PublicInbox::Search->new($self->{git_dir});
48         };
49 }
50
51 sub mm {
52         my ($self) = @_;
53         $self->{mm} ||= eval {
54                 my $mm = PublicInbox::Msgmap->new($self->{git_dir});
55
56                 # may be needed if we run low on handles
57                 defer_weaken($self, 'mm');
58                 $mm;
59         };
60 }
61
62 sub search {
63         my ($self) = @_;
64         $self->{search} ||= eval {
65                 my $search = PublicInbox::Search->new($self->{git_dir});
66
67                 # may be needed if we run low on handles
68                 defer_weaken($self, 'search');
69                 $search;
70         };
71 }
72
73 sub description {
74         my ($self) = @_;
75         open my $fh, '<', "$self->{git_dir}/description" or return '';
76         my $desc = eval { local $/; <$fh> };
77         chomp $desc;
78         $desc =~ s/\s+/ /smg;
79         $desc;
80 }
81
82 sub update {
83         my ($self, $new) = @_;
84         $self->{address} = $new->{address};
85         $self->{domain} = $new->{domain};
86         if ($self->{git_dir} ne $new->{git_dir}) {
87                 # new git_dir requires a new mm and gcf
88                 $self->{mm} = $self->{gcf} = undef;
89                 $self->{git_dir} = $new->{git_dir};
90         }
91 }
92
93 1;