work towards s/Moose/Moo/g
[p5sagit/Promulger.git] / lib / Promulger / List.pm
CommitLineData
514dce63 1package Promulger::List;
243baf4d 2use Moo;
514dce63 3
f5baca29 4use autodie ':all';
514dce63 5use Carp;
f5baca29 6use Path::Class;
7use Fcntl ':flock';
9bfd7b60 8use Tie::File;
243baf4d 9use File::Slurp qw/read_file, write_file/;
10use Data::Dumper;
11$Data::Dumper::Purity = 1;
514dce63 12
21baaef0 13use Promulger::Config;
14
514dce63 15has listname => (
16 is => 'ro',
243baf4d 17 isa => sub { $_[0] =~ /^\w+$/ or die "listname must be a string" },
514dce63 18 required => 1,
19);
20
21has active => (
22 is => 'rw',
243baf4d 23 isa => sub { ($_[0] == 0 || $_[0] == 1) or die "active must be 0 or 1" },
514dce63 24 required => 1,
243baf4d 25 default => sub { 1 },
514dce63 26);
27
21baaef0 28has subscribers => (
29 is => 'rw',
243baf4d 30 isa => sub { ref $_[0] eq 'HASH' or die "subscribers must be a hashref" },
21baaef0 31 required => 1,
32 default => sub { {} },
33);
34
21baaef0 35sub resolve {
9bfd7b60 36 my ($self, $proto) = @_;
21baaef0 37 $proto =~ s/-request$//;
38 my $path = find_path_for($proto);
39 my $maybe_list;
40 eval {
41 $maybe_list = __PACKAGE__->load($path->stringify);
42 };
43 return $maybe_list;
44}
f5baca29 45
21baaef0 46sub subscribe {
9bfd7b60 47 my ($self, $new) = @_;
8ad89cb2 48 return if $self->subscribers->{$new};
49 $self->subscribers->{$new} = 1;
50 $self->store(find_path_for($self->listname)->stringify);
51 return 1;
21baaef0 52}
f5baca29 53
21baaef0 54sub unsubscribe {
9bfd7b60 55 my ($self, $ex) = @_;
8ad89cb2 56 return unless exists $self->subscribers->{$ex};
57 delete $self->subscribers->{$ex};
58 $self->store(find_path_for($self->listname)->stringify);
59 return 1;
21baaef0 60}
f5baca29 61
21baaef0 62# XXX implement ACLs and other shinies -- apeiron, 2010-03-13
63sub accept_posts_from {
9bfd7b60 64 my ($self, $sender) = @_;
8ad89cb2 65 return grep { $sender eq $_ } keys %{$self->subscribers};
21baaef0 66}
f5baca29 67
68sub setup {
9bfd7b60 69 my ($self) = @_;
21baaef0 70 my $config = Promulger::Config->config;
514dce63 71 my $name = $self->listname;
9bfd7b60 72 croak "${name} already a known list" if $self->resolve($name);
21baaef0 73 my $path = find_path_for($name);
f5baca29 74
9bfd7b60 75 my $tie = tie my @aliases, 'Tie::File', $config->{aliases};
76 $tie->flock;
77 my @list_aliases = ($name, "${name}-request");
21baaef0 78
9bfd7b60 79 for my $list_alias (@list_aliases) {
80 if(grep { /^${list_alias}:/ } @aliases) {
81 croak "${list_alias} already in $config->{aliases}";
514dce63 82 }
9bfd7b60 83 push @aliases,
84 qq(${list_alias}: "|$config->{bin_root}/pmg msg -c $config->{config_file}"\n);
514dce63 85 }
21baaef0 86
f5baca29 87 $self->store($path->stringify);
9bfd7b60 88}
89
90sub delete {
91 my ($self) = @_;
92 my $config = Promulger::Config->config;
93 my $name = $self->listname;
94
95 my $tie = tie my @aliases, 'Tie::File', $config->{aliases};
96 $tie->flock;
97
98 my @list_aliases = ($name, "${name}-request");
99 @aliases = grep {
100 $_ !~ /^$list_aliases[0]:/ &&
101 $_ !~ /^$list_aliases[1]:/
102 } @aliases;
103
8ad89cb2 104 unlink find_path_for($self->listname)->stringify;
514dce63 105}
106
21baaef0 107sub find_path_for {
108 my ($proto) = @_;
109 my $path = file(Promulger::Config->config->{list_home}, $proto . ".list");
9bfd7b60 110 return $path;
21baaef0 111}
112
243baf4d 113sub store {
114 my ($self, $path) = @_;
115 my $dumped = 'do { my '. Dumper($self) . '; $VAR1; }';
116 write_file($path, $dumped);
117}
118
119sub load {
120 my ($class, $path) = @_;
121 return do $path;
122}
123
21baaef0 124'http://mitpress.mit.edu/sicp/';