/[notice-sender]/trunk/sender.pl
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/sender.pl

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 17 by dpavlin, Sun May 15 16:32:36 2005 UTC revision 72 by dpavlin, Mon Aug 22 20:24:04 2005 UTC
# Line 1  Line 1 
1  #!/usr/bin/perl -w  #!/usr/bin/perl -w
2    
3  use strict;  use strict;
4  use Class::DBI::Loader::Pg;  use blib;
5    use Nos 0.7;
6  use Getopt::Long;  use Getopt::Long;
 use Mail::CheckUser qw(check_email);  
 use Email::Valid;  
 use Email::Send;  
7    
8  =head1 NAME  =head1 NAME
9    
# Line 13  sender.pl - command line notify sender u Line 11  sender.pl - command line notify sender u
11    
12  =head1 SYNOPSYS  =head1 SYNOPSYS
13    
14     sender.pl --create=mylist
15     sender.pl --drop=mylist
16   sender.pl --add=mylist members.txt   sender.pl --add=mylist members.txt
17     sender.pl --delete=mylist members.txt
18   sender.pl --list[=mylist]   sender.pl --list[=mylist]
19   sender.pl --queue[=mylist message.txt]   sender.pl --queue[=mylist message.txt]
20   sender.pl --send=mylist   sender.pl --send=mylist
21    
22    In C</etc/aliases> something like:
23    
24     mylist: "| cd /path/to && ./sender.pl --inbox=mylist"
25    
26  =head2 Command options  =head2 Command options
27    
28  =over 20  =over 20
# Line 26  sender.pl - command line notify sender u Line 31  sender.pl - command line notify sender u
31    
32  my $debug = 0;  my $debug = 0;
33  my $verbose = 0;  my $verbose = 0;
34  my $list_opt;  my $opt;
 my $add_opt;  
 my $queue_opt;  
 my $send_opt;  
35    
36  my $result = GetOptions(  my $result = GetOptions(
37          "list:s" => \$list_opt,          "create=s" => \$opt->{'create'},
38          "add=s" => \$add_opt,          "drop=s" => \$opt->{'drop'},
39          "queue:s" => \$queue_opt,          "list:s" => \$opt->{'list'},
40          "send:s" => \$send_opt,          "add=s" => \$opt->{'add'},
41            "delete=s" => \$opt->{'delete'},
42            "queue:s" => \$opt->{'queue'},
43            "send:s" => \$opt->{'send'},
44            "inbox=s" => \$opt->{'inbox'},
45          "debug" => \$debug,          "debug" => \$debug,
46          "verbose" => \$verbose,          "verbose" => \$verbose,
47            "from=s" => \$opt->{'from'},
48            "driver=s" => \$opt->{'email_send_driver'},
49            "sleep=i" => \$opt->{'sleep'},
50            "aliases=s" => \$opt->{'aliases'},
51  );  );
52    
53    my $nos = new Nos(
54  my $loader = Class::DBI::Loader::Pg->new(          dsn => 'dbi:Pg:dbname=notices',
55          debug           => $debug,          user => 'dpavlin',
56          dsn             => "dbi:Pg:dbname=notices",          passwd => '',
57          user            => "dpavlin",          debug => $debug,
58          password        => "",          verbose => $verbose,
         namespace       => "Noticer",  
 #       additional_classes      => qw/Class::DBI::AbstractSearch/,  
 #       additional_base_classes => qw/My::Stuff/,  
         relationships   => 1,  
59  );  );
60    
61    my $loader = $nos->{'loader'} || die "can't find loader?";
62    
63  my $lists = $loader->find_class('lists');  my $lists = $loader->find_class('lists');
64  my $users = $loader->find_class('users');  my $users = $loader->find_class('users');
65  my $user_list = $loader->find_class('user_list');  my $user_list = $loader->find_class('user_list');
# Line 66  $queue->set_sql( list_queue => qq{ Line 74  $queue->set_sql( list_queue => qq{
74          JOIN lists on list_id = lists.id          JOIN lists on list_id = lists.id
75  } );  } );
76    
77    my $list_name;
78    
79    =item --aliases=/full/path/to/aliases
80    
81    Optional parametar C<--aliases> can be used to specify aliases file other
82    than default C</etc/aliases>.
83    
84    =cut
85    
86    my $aliases = $opt->{'aliases'} || '/etc/aliases';
87    
88    
89    =item --create=list_name my-list@example.com
90    
91    Adds new list. You can also feed list name as first line to C<STDIN>.
92    
93    You can also add C<--from='Full name of list'> to specify full name (comment)
94    in outgoing e-mail.
95    
96    =cut
97    
98    if ($list_name = $opt->{'create'}) {
99    
100            my $email = shift @ARGV || <>;
101            chomp($email);
102    
103            die "need e-mail address for list (as argument or on STDIN)\n" unless ($email);
104    
105            my $id = $nos->create_list(
106                    list => $list_name,
107                    from => ($opt->{'from'} || ''),
108                    email => $email,
109                    aliases => $aliases,
110            ) || die "can't add list $list_name\n";
111    
112            print "added list $list_name with ID $id\n";
113    
114    
115    =item --drop=list_name
116    
117    Remove list.
118    
119    Optional parametar C<--aliases='/full/path/to/aliases'> can be used to
120    specify aliases file other than C</etc/aliases>.
121    
122    =cut
123    
124    } elsif ($list_name = $opt->{'drop'}) {
125    
126            my $id = $nos->drop_list(
127                    list => $list_name,
128                    aliases => $aliases,
129            ) || die "can't remove list $list_name\n";
130    
131            print "drop list $list_name with ID $id\n";
132    
133    
134  =item --list[=list_name]  =item --list[=list_name]
135    
# Line 76  on that list. Line 140  on that list.
140    
141  =cut  =cut
142    
143  if (defined($list_opt)) {  } elsif (defined($list_name = $opt->{'list'})) {
144    
145          my @lists;          my @lists;
146          if ($list_opt ne '') {  
147                  @lists = $lists->search( name=> $list_opt )->first || die "can't find list $list_opt";          if ($list_name ne '') {
148                    @lists = $lists->search( name=> $list_name )->first || die "can't find list $list_name";
149          } else {          } else {
150                  @lists = $lists->retrieve_all;                  @lists = $lists->retrieve_all;
151          }          }
152    
153          foreach my $list (@lists) {          foreach my $list (@lists) {
154                  print $list->name," <",$list->email,">\n";                  print $list->name,": ",$list->from_addr," <",$list->email,">\n";
155                  foreach my $user_on_list ($user_list->search(list_id => $list->id)) {                  foreach my $u ($nos->list_members( list => $list->name )) {
156                          my $user = $users->retrieve( id => $user_on_list->user_id );                          print "\t",$u->{'name'}, " <", $u->{'email'}, ">",( $u->{'ext_id'} ? ' ['.$u->{'ext_id'}.']' : '' ),"\n";
                         print "\t",$user->full_name," <", $user->email, ">\n";  
157                  }                  }
158          }          }
159    
160    
161  =item --add=list_name  =item --add=list_name
162    
163  Add users to list. Users are stored in file (which can be supplied as  Add users to list. Users are stored in file (which can be supplied as
# Line 102  argument) or read from C<STDIN>. List sh Line 168  argument) or read from C<STDIN>. List sh
168    
169  =cut  =cut
170    
171  } elsif ($add_opt) {  } elsif ($list_name = $opt->{'add'}) {
172          #my $noticer = $loader->find_class('Noticer') || die "can't find my class!";  
173          my $list = $lists->find_or_create({          my $list = $nos->_get_list($list_name) || die "can't find list $list_name\n";
                 name => $add_opt,  
         }) || die "can't add list $add_opt\n";  
174    
175          my $added = 0;          my $added = 0;
176    
# Line 114  argument) or read from C<STDIN>. List sh Line 178  argument) or read from C<STDIN>. List sh
178                  chomp;                  chomp;
179                  next if (/^#/ || /^\s*$/);                  next if (/^#/ || /^\s*$/);
180                  my ($email, $name) = split(/\s+/,$_, 2);                  my ($email, $name) = split(/\s+/,$_, 2);
181                  $name ||= '';                  $added++ if ($nos->add_member_to_list( email => $email, name => $name, list => $list_name ));
                 if (! Email::Valid->address($email)) {  
                         print "SKIPPING $name <$email>\n";  
                         next;  
                 }  
                 print "# $name <$email>\n";  
                 my $this_user = $users->find_or_create({  
                         email => $email,  
                         full_name => $name,  
                 }) || die "can't find or create member\n";  
                 my $user_on_list = $user_list->find_or_create({  
                         user_id => $this_user->id,  
                         list_id => $list->id,  
                 }) || die "can't add user to list";  
                 $added++;  
182          }          }
183    
184          foreach my $c_name ($loader->tables) {          print "list ",$list->name," has $added users\n";
185                  my $c = $loader->find_class($c_name)|| die "can't find $c_name";  
186                  $c->dbi_commit();  
187    =item --delete=list_name
188    
189    Delete users from list. User e-mails can be stored in file (which can be
190    supplied as argument) or read from C<STDIN>.
191    
192    =cut
193    } elsif ($list_name = $opt->{'delete'}) {
194    
195            my $list = $nos->_get_list($list_name) || die "can't find list $list_name\n";
196    
197            my $deleted = 0;
198    
199            while(<>) {
200                    chomp;
201                    next if (/^#/ || /^\s*$/);
202                    my $email = $_;
203                    $deleted++ if ($nos->delete_member_from_list( email => $email, list => $list_name ));
204          }          }
205    
206          print "list ",$list->name," has $added users\n";          print "list ",$list->name," lost $deleted users\n";
207    
208    
209  =item --queue[=list_name]  =item --queue[=list_name]
210    
# Line 148  add C<--verbose> flag, it will display a Line 216  add C<--verbose> flag, it will display a
216    
217  =cut  =cut
218    
219  } elsif (defined($queue_opt)) {  } elsif (defined($list_name = $opt->{'queue'})) {
220    
221          if ($queue_opt ne '') {          if ($list_name ne '') {
222                  # add message to list queue                  # add message to list queue
223    
                 my $this_list = $lists->search(  
                         name => $queue_opt,  
                 )->first || die "can't find list $queue_opt";  
   
224                  my $message_text;                  my $message_text;
225                  while(<>) {                  while(<>) {
226                          $message_text .= $_;                          $message_text .= $_;
227                  }                  }
228    
229                  die "no message" unless ($message_text);                  my $id = $nos->add_message_to_list(
230                            list => $list_name,
231                  my $this_message = $messages->find_or_create({                          message => $message_text,
232                          message => $message_text                  ) || die "can't add message to list $list_name\n";
                 }) || die "can't insert message";  
233    
234                  $this_message->dbi_commit() || die "can't add message";                  print "added message $id to list $list_name\n";
   
                 $queue->find_or_create({  
                         message_id => $this_message->id,  
                         list_id => $this_list->id,  
                 }) || die "can't add message ",$this_message->id," to list ",$this_list->id, ": ",$this_list->name;  
   
                 $queue->dbi_commit || die "can't add message to list ",$this_list->name;  
   
                 print "added message ",$this_message->id, " to list ",$this_list->name,"\n";  
235    
236          } else {          } else {
237                  # list messages in queue                          # list messages in queue        
# Line 192  add C<--verbose> flag, it will display a Line 246  add C<--verbose> flag, it will display a
246                          my $msg = $m->message_id->message;                          my $msg = $m->message_id->message;
247                          $msg =~ s/\s+/ /gs;                          $msg =~ s/\s+/ /gs;
248    
249                          $l .= sprintf(" %-10s %15s : ", $m->list_id->name, $date);                          $l .= sprintf(" %-15s %15s : ", $m->list_id->name, $date);
250                          $l .= substr($msg, 0, 79 - length($l));                          $l .= substr($msg, 0, 79 - length($l));
251    
252                          print "$l\n";                          print "$l\n";
# Line 200  add C<--verbose> flag, it will display a Line 254  add C<--verbose> flag, it will display a
254    
255          }          }
256    
257    
258  =item --send[=list_name]  =item --send[=list_name]
259    
260  Send e-mails waiting in queue, or with optional argument, just send messages  Send e-mails waiting in queue, or with optional argument, just send messages
261  for single list.  for single list.
262    
263    Optional argument C<--driver=smtp> forces sending using SMTP server at
264    localhost (127.0.0.1).
265    
266    Optional argument C<--sleep=42> defines that sender will sleep 42 seconds
267    between sending e-mail.
268    
269  =cut  =cut
270    
271  } elsif (defined($send_opt)) {  } elsif (defined($list_name = $opt->{'send'})) {
272    
273          my $my_q;          unless ($opt->{'email_send_driver'}) {
274          if ($send_opt ne '') {                  print "WARNING: this will dump debugging output to STDERR\n";
275                  my $l_id = $lists->search_like( name => $send_opt )->first ||                  print "enter alternative driver (e.g. smtp): ";
276                          die "can't find list $send_opt";                  my $d = <STDIN>;
277                  $my_q = $queue->search_like( list_id => $l_id ) ||                  chomp($d);
278                          die "can't find list $send_opt";                  $opt->{'email_send_driver'} = $d;
         } else {  
                 $my_q = $queue->retrieve_all;  
279          }          }
280    
281          while (my $m = $my_q->next) {          $nos->send_queued_messages(
282                  next if ($m->all_sent);                  list => $list_name,
283                    driver => $opt->{'email_send_driver'},
284                    sleep => $opt->{'sleep'},
285            );
286    
                 print "sending message ",$m->message_id," enqueued on ",$m->date," to list ",$m->list_id->name,"\n";  
                 my $msg = $m->message_id->message;  
287    
288                  foreach my $u ($user_list->search(list_id => $m->list_id)) {  =item --inbox=list_name
289    
290                          my $hdr = "To: ".$u->user_id->full_name." <". $u->user_id->email. ">\n";  Feed incomming message back into notice sender.
291    
292                          if ($sent->search( message_id => $m->message_id, user_id => $u->user_id )) {  =cut
293                                  print "SKIP ",$u->user_id->email," message allready sent\n";  
294                          } else {  } elsif ($list_name = $opt->{'inbox'}) {
295                                  print "\t",$u->user_id->email,"\n";  
296                                  send IO => "$hdr\n$msg";          my $message;
297                                  $sent->create({          while(<>) {
298                                          message_id => $m->message_id,                  $message .= $_;
                                         user_id => $u->user_id,  
                                 });  
                                 $sent->dbi_commit;  
                         }  
                 }  
                 $m->all_sent(1);  
                 $m->update;  
                 $m->dbi_commit;  
299          }          }
300    
301            $nos->inbox_message(
302                    list => $list_name,
303                    message => $message,
304            ) || die "can't receive message for list $list_name";
305    
306    
307  } else  {  } else  {
308          die "see perldoc $0 for help";          die "see perldoc $0 for help\n";
309  }  }
310    
311  =back  =back

Legend:
Removed from v.17  
changed lines
  Added in v.72

  ViewVC Help
Powered by ViewVC 1.1.26