One thing that I pride myself on is my own responsiveness when people send me email, leave me voicemail, letters or whatever form of communication. I'm terrible about initiating correspondance, but I'm great at keeping up with replies to correspondance that I've recieved.
It doesn't happen often, but every once in a while someone from Perl Monks sends me a private "/msg" from CB and I'll miss it. I may not see it for several days and if my life outside the Monastery is really busy it may even be weeks before I notice it.
When it does happen I feel really horrible about that like I've ignored a realy good friend at a party.
With that in mind and as well as some curiosity about a couple of things that I wanted to look at (more on that in a bit) I decided to create a tool that would look at the XML ticker for the Message Inbox (see: What XML generators are currently available on PerlMonks? sitedoclet) scrape off the latest messages there and send them to my pager and email.
This also was a perfect excuse for me to explore several CPAN modules at the same time. Those were:
This was developed and tested on a Linux box with Perl 5.8.6. The backend database is Postgres 8.1.
Without further ado, let's look at the code and what's in it.
One of the features that I'm always keeping an eye out for is a better way to store and retrieve configuration data for an application. I've tried all sorts of methods from using Windows style configuration files and the CPAN module AppConfig and flat files and all sorts of methods including rolling my own techniques. Then, in a completely unrelated bit of work I was researching I tripped across XML::Simple. In its man page it gave the following code sniglet:
which turned out to implement behavior that looked for a file called MyProgram.xml (where MyProgram was the basename of the script being run) and would return a nested hash into the scalar $config consisting of the XML embedded in the XML file. Nice....use XML::Simple; my $config = XMLin();
So for input to my script you need a XML file in the same directory that the script "lives in" to configure the configuration settings that the script needs as follows:
<config> <perlmonks> <userid>your_pm_userid_here</userid> <password>your_passowrd_here</password> </perlmonks> <database> <driver>Pg</driver> <dbname>pmdata</dbname> <dbhost>your.database.host.here</dbhost> <dbuser>dbuser</dbuser> <dbpass>secret</dbpass> </database> <notification> <mailfrom>nobody@wherever.net</mailfrom> <pager>email@pagercompany.com</pager> <email>youself@yourisp.net</email> </notification> </config>
Each section of the configuration file should be self-explanitory. Each value setting should also be self-explanitory. I love XML for that. :-)
The script itself is pretty straight forward in its functionality. The steps are:
So... why the database you might ask. There are two very valid reasons I do that:
The table that I created in the database is pretty straight forward:
CREATE TABLE messages ( message_id integer NOT NULL, status character varying(20) NOT NULL, time_rcvd timestamp without time zone NOT NULL, author character varying(20) NOT NULL, content character varying(200) NOT NULL );
Without further ado, here's the script itself:
#!/usr/bin/perl -w ###################################################################### +## # # $Id: PmChatPage.pl,v 1.4 2005/11/02 16:20:38 peter Exp $ # # $Log: PmChatPage.pl,v $ # Revision 1.4 2005/11/02 16:20:38 peter # final touches to get it ready to be posted as a CUFP # # Revision 1.3 2005/11/01 03:39:27 peter # DOH! Forgot to load the notification addresses from the config fil +e. # # Revision 1.2 2005/11/01 03:33:57 peter # autodetect of host it is running on # # Revision 1.1.1.1 2005/11/01 03:28:40 peter # This is the beginning of a beautiful thing. # # # Author: Peter L. Berghold # # Purpose: Retrieve current messages from Perl Monks and send a copy # to my pager and email so I can stay on top of what is happ +ening # at my favorite web site. # And it cannot be overlooked that this is for my own # amuzment and I amuze so easily. # ###################################################################### +## $|=1; use strict; use DBI; use XML::Simple; use Data::Dumper; use LWP::UserAgent; use HTTP::Request::Common; use HTTP::Cookies; use MIME::Lite; # # These variables will be configured by the PmChatPage.xml # contents via the XML::Simple parser. # ---------------------------------------------------------------- my $conf_parser=new XML::Simple; my $config= $conf_parser->XMLin(); my $DSN = sprintf("DBI:%s:database=%s;host=%s", $config->{database}->{driver}, $config->{database}->{dbname}, $config->{database}->{dbhost}); my $dbh = DBI->connect($DSN, $config->{database}->{dbuser}, $config->{database}->{dbpass}, {RaiseError=>1}) or die DBI::errstr; my $ua=LWP::UserAgent->new(); my $pm="http://www.perlmonks.org/index.pl"; $ua->cookie_jar({}); # set up a temporary cookie jar for my session login($ua,$config); # Log into Perl Monks # # Check my messages.... my @msg_list=get_messages($ua,get_max_id($dbh)); # # If there are any, process them. if ($#msg_list > -1 ) { process_messages($dbh,$config,@msg_list); } exit(0); # # This sub retrieves the highest id of the messages stored in the data +base sub get_max_id { my $dbh = shift; my $sth = $dbh->prepare(qq@ select max(message_id) as message_id from messages @) or die $dbh->errstr; $sth->execute(); my $row=$sth->fetchrow_hashref; return $row->{message_id}; } # # Logs into PerlMonks sub login { my ($ua,$config)=@_; my $r=$ua->request( POST ($pm,[ op=> 'login', user=> $config->{perlmonks}->{userid} +, passwd => $config->{perlmonks}->{pass +word}, expires => '+1y', node_id => '16046', ticker=>'yes' ])); } # # Slurp in the messages from the XML ticker. sub get_messages { my ($ua,$msg_id)=@_; my $xs=new XML::Simple(); my $response = $ua->request(GET("$pm?node_id=15848;since_id=$msg_id" +)); my $tree=$xs->XMLin($response->content); my @msgs=(); if ($tree->{message}) { if ( ref($tree->{message}) eq 'ARRAY' ) { push @msgs,@{$tree->{message}}; } else { push @msgs,$tree->{message}; } } return @msgs; } # # Store the messages into the database and send the notifications out. sub process_messages { my $dbh=shift; my $config=shift; my $sth=$dbh->prepare(qq( insert into messages(message_id,status,time_rcvd,author,content) values (?,?,?,?,?) ) ) or die $dbh->errstr; foreach my $msg (@_) { my $raw_time = $msg->{time}; my $msg_id = $msg->{message_id}; my $content = $msg->{content}; my $status = $msg->{status}; my $author = $msg->{author}; $content =~ s/\n+//g; $raw_time =~ m@^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})$@; my ($year,$month,$day,$hour,$minute,$seconds)=($1,$2,$3,$4,$5,$6); my $timestamp=sprintf("%0.4d-%0.2d-%0.2d %0.2d:%0.2d:%0.2d", $year,$month,$day,$hour,$minute,$seconds ); $sth->execute($msg_id,$status,$timestamp,$author,$content) or die $sth->errstr; my $mail_text = sprintf("Message from %s\n%s",$author,$content); my $mail_msg = MIME::Lite->new( From => $config->{notification}->{m +ailfrom}, To => $config->{notification}->{pag +er}, Cc => $config->{notification}->{ema +il}, Subject => 'Messages on PerlMonks', Type=> 'TEXT', Data=> $mail_text ); $mail_msg->send; } }
I run this script on a Linux box I have at home out of cron. I run it about once every 15 minutes between 1300GMT and 0300GMT daily.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Send private PM messages to my pager.
by thor (Priest) on Nov 02, 2005 at 19:28 UTC | |
by Roy Johnson (Monsignor) on Nov 02, 2005 at 22:45 UTC |