use strict;
use warnings;
+use App::Cmd::Setup -command;
+
+use Promulger::Config;
+
+sub opt_spec {
+ return (
+ [ "config|c=s", "configuration file", { required => 1 } ],
+ );
+}
+
+sub validate_args {
+ my ($self, $opt, $args) = @_;
+ my $cf = $opt->{config};
+
+ unless(-e $cf) {
+ die "Config file $cf doesn't exist\n";
+ }
+ unless(-f $cf) {
+ die "Config file $cf not a file\n";
+ }
+ unless(-r $cf) {
+ die "Config file $cf not readable\n";
+ }
+
+ Promulger::Config->config({ Config::General->new($cf)->getall });
+ Promulger::Config->config->{config}{config_file} = $cf;
+}
1;
local $/;
<STDIN>
};
- Promulger::Dispatch::dispatch($message, $self->{config});
+ Promulger::Dispatch::dispatch($message);
}
1;
use App::Promulger -command;
use Promulger::List;
-use Config::General;
sub abstract {
return "creates a new list";
}
-sub opt_spec {
- return (
- [ "config|c=s", "configuration file", { required => 1 } ],
- );
-}
-
-sub validate_args {
- my ($self, $opt, $args) = @_;
- my $cf = $opt->{config};
-
- unless(-e $cf) {
- die "Config file $cf doesn't exist\n";
- }
- unless(-f $cf) {
- die "Config file $cf not a file\n";
- }
- unless(-r $cf) {
- die "Config file $cf not readable\n";
- }
-
- $self->{config} = { Config::General->new($cf)->getall };
- $self->{config}{config_file} = $cf;
-}
-
-
sub run {
my ($self, $opt, $args) = @_;
@$args == 1 or die "pmg newlist needs a list name\n";
my $list = Promulger::List->new(
listname => $args->[0],
);
- $list->setup($self->{config});
+ $list->setup;
}
1;
--- /dev/null
+package Promulger::Config;
+
+my $config;
+sub config {
+ my $class = shift;
+ if(my $new = shift) {
+ $config = $new;
+ }
+ return $config;
+};
+
+'http://reductivelabs.com/products/puppet/';
use Email::Sender::Simple qw(sendmail);
use Mail::Verp;
+use Promulger::Config;
+
+# XXX no bounce parsing yet -- apeiron, 2010-03-13
sub dispatch {
- my($message, $config) = @_;
+ my($message) = @_;
+ my $config = Promulger::Config->config;
my $email = Email::Simple->new($message);
my $recipient = $email->header('To');
}
sub handle_request {
- my ($list, $sender, $recipient, $subject, $config) = @_;
+ my ($list, $sender, $recipient, $subject) = @_;
if($subject =~ /^subscribe/i) {
- $list->subscribe($sender, $config)
- or already_subscribed($list, $sender, $config);
+ $list->subscribe($sender)
+ or already_subscribed($list, $sender);
} elsif($subject =~ /^unsubscribe/i) {
- $list->unsubscribe($sender, $config)
- or not_subscribed($list, $sender, $config);
+ $list->unsubscribe($sender)
+ or not_subscribed($list, $sender);
}
}
}
}
-sub reject {}
-sub not_subscribed {}
-sub already_subscribed {}
+# XXX make this actually not suck -- apeiron, 2010-03-13
+sub reject {
+ my($recipient, $sender) = @_;
+ my $email = Email::Simple->create(
+ header => [
+ From => $recipient,
+ To => $sender,
+ Subject => 'Rejected',
+ ],
+ body => <<BODY,
+Sorry, your message to $recipient has been denied.
+BODY
+ );
+ sendmail($email);
+}
+
+sub not_subscribed {
+ my($list, $sender) = @_;
+ my $list_address = $list->address;
+ my $email = Email::Simple->create(
+ header => [
+ From => $list->admin_address,
+ To => $sender,
+ Subject => 'Not subscribed',
+ ],
+ body => <<BODY,
+Sorry, you are not subscribed to $list_address;
+BODY
+ );
+ sendmail($email);
+}
+
+sub already_subscribed {
+ my($list, $sender) = @_;
+ my $list_address = $list->address;
+ my $email = Email::Simple->create(
+ header => [
+ From => $list->admin_address,
+ To => $sender,
+ Subject => 'Already subscribed',
+ ],
+ body => <<BODY,
+Sorry, you are already subscribed to $list_address;
+BODY
+ );
+ sendmail($email);
+}
'http://www.shadowcat.co.uk/blog/matt-s-trout/oh-subdispatch-oh-subdispatch/';
use Path::Class;
use Fcntl ':flock';
+use Promulger::Config;
+
has listname => (
is => 'ro',
isa => 'Str',
default => 1,
);
+has subscribers => (
+ is => 'rw',
+ isa => 'HashRef',
+ required => 1,
+ default => sub { {} },
+);
+
with Storage (
format => 'JSON',
io => 'File',
);
-sub resolve {}
+sub resolve {
+ my($proto) = @_;
+ $proto =~ s/-request$//;
+ my $path = find_path_for($proto);
+ my $maybe_list;
+ eval {
+ $maybe_list = __PACKAGE__->load($path->stringify);
+ };
+ return $maybe_list;
+}
-sub subscribe {}
+sub subscribe {
+ my($self, $new) = @_;
+ return if $self->subscribers->at($new);
+ $self->subscribers->put($new, 1);
+ $self->store(find_path_for($self->name));
+}
-sub unsubscribe {}
+sub unsubscribe {
+ my($self, $ex) = @_;
+ return unless $self->subscribers->at($ex);
+ $self->subscribers->delete($ex);
+ $self->store(find_path_for($self->name));
+}
-sub accept_posts_from {}
+# XXX implement ACLs and other shinies -- apeiron, 2010-03-13
+sub accept_posts_from {
+ my($self, $sender) = @_;
+ return grep { $sender eq $_ } @{$self->subscribers};
+}
sub setup {
- my($self, $config) = @_;
+ my($self) = @_;
+ my $config = Promulger::Config->config;
my $name = $self->listname;
- my $path = file($config->{list_home}, $name . ".list");
- eval {
- __PACKAGE__->load($path->stringify);
- };
- croak "${name} already a known list" unless $@;
+ croak "${name} already a known list" if resolve($name);
+ my $path = find_path_for($name);
open my $fh, '+<', $config->{aliases};
flock $fh, LOCK_EX;
my @current_contents = <$fh>;
my @aliases = ($name, "${name}-request");
+
for my $alias (@aliases) {
if(grep { /^${alias}:/ } @current_contents) {
croak "${alias} already in $config->{aliases}";
push @current_contents,
qq(${alias}: "|$config->{bin_root}/pmg msg -c $config->{config_file}"\n);
}
+
$self->store($path->stringify);
print $fh @current_contents;
flock $fh, LOCK_UN;
}
-1;
+sub find_path_for {
+ my ($proto) = @_;
+ my $path = file(Promulger::Config->config->{list_home}, $proto . ".list");
+}
+
+'http://mitpress.mit.edu/sicp/';