#!/usr/bin/perl -w # $Id: mood_monitor.pl 513 2004-12-01 10:55:11Z ralphm $ use strict; use open ':utf8'; use Jabber::Connection; use Jabber::NodeFactory; use Jabber::NS qw(:all); use DBI; use XML::Simple; use Getopt::Long; use constant NS_PUBSUB_EVENT => 'http://jabber.org/protocol/pubsub#event'; use constant NS_MOOD => 'http://jabber.org/protocol/mood'; use constant NS_MOODS => 'http://jabber.org/protocol/moods'; # old! my %optctl = (); $optctl{config} = ""; &GetOptions(\%optctl, "config=s"); $optctl{config} = undef unless ($optctl{config} ne ""); my $config = XMLin($optctl{config}); my $nf = new Jabber::NodeFactory; # Create a new db connection my ($dbh, $sth); &db_connect; # Delete all mood entries #$dbh->do("DELETE FROM moods"); # Update process list entry $dbh->do("DELETE FROM process_list WHERE name='mood_monitor'"); $dbh->do("INSERT INTO process_list (name, pid) VALUES ('mood_monitor', $$)"); # Open connection to Jabber server my $c = new Jabber::Connection( server => $config->{jabber}->{server}, log => 1, debug => 1, ); $c->connect or die "oops: ".$c->lastError; # Register various handlers $c->register_handler('message', \&message); # Identify and authenticate with the server $c->auth($config->{jabber}->{username}, $config->{jabber}->{password}, $config->{jabber}->{resource}); # Send presence #$c->send(''); # Start processing loop $c->start(); # # db_connect - connect to the database # sub db_connect { $dbh = DBI->connect("dbi:".$config->{database}->{driver}.":".$config->{database}->{dsn}, $config->{database}->{login}, $config->{database}->{password}) or die "Cannot connect to database ($!)\n"; } # # getdata - return the data inside the element with name $name or empty # sub getdata { my $node = shift; my $name = shift; my $tag; return ($tag = $node->getTag($name)) ? $tag->data : ""; } sub message { my $message = shift; # only handle messages with a pubsub notification my $event = $message->getTag('', NS_PUBSUB_EVENT); return unless defined $event; # get items my $items = $event->getTag('items'); return unless defined $items; my $node = $items->attr('node'); return unless $node =~ /^ralphm\/mood\/(.+)?$/; my $jid = $1; # process items my @items_children = $items->getTag('item'); foreach my $item (@items_children) { # process payload # only handle my namespaces my $mood; if (not ($mood = $item->getTag('mood', NS_MOOD))) { if (not ($mood = $item->getTag('mood', NS_MOODS))) { # old namespace next; } } my $show = getdata($mood, 'value'); my $status = getdata($mood, 'text'); if (!$show) { my @children = $mood->getChildren(); if ($#children >= 0) { my $first = $children[0]->name(); if ($first ne 'text' and $first ne 'value') { $show = $first; } } } print STDERR "Got mood '$show', text = '$status' for $jid\n"; $show = "neutral" if (!$show); $dbh->ping or &db_connect; $sth = $dbh->prepare("SELECT jid FROM moods WHERE jid=?"); $sth->execute($jid); my $exists = 0; if ( my @row = $sth->fetchrow_array ) { $exists = 1; } # prepare database query if ( $exists ) { # update the mood information $sth = $dbh->prepare('UPDATE moods SET "status"=?, "show"=?, "date"=now() WHERE jid=?'); } else { # insert a new record with the mood information $sth = $dbh->prepare( 'INSERT INTO moods '. '("status", "show", "jid") '. 'VALUES (?, ?, ?)' ); } # execute the actual query $sth->execute($status, $show, $jid); } return r_HANDLED; }