/[irc-logger]/trunk/bin/irc-logger.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/bin/irc-logger.pl

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

revision 119 by dpavlin, Fri Mar 14 00:17:49 2008 UTC revision 132 by dpavlin, Tue Apr 1 19:04:32 2008 UTC
# Line 2  Line 2 
2  use strict;  use strict;
3  $|++;  $|++;
4    
5  use POE qw(Component::IRC Component::Server::HTTP);  use POE qw(Component::IRC Component::Server::HTTP Component::Client::HTTP);
6  use HTTP::Status;  use HTTP::Status;
7  use DBI;  use DBI;
8  use Regexp::Common qw /URI/;  use Regexp::Common qw /URI/;
# Line 18  use DateTime::Format::ISO8601; Line 18  use DateTime::Format::ISO8601;
18  use Carp qw/confess/;  use Carp qw/confess/;
19  use XML::Feed;  use XML::Feed;
20  use DateTime::Format::Flexible;  use DateTime::Format::Flexible;
21  use IPC::DirQueue;  use Encode;
 use File::Slurp;  
22    
23  =head1 NAME  =head1 NAME
24    
# Line 58  my $irc_config = { Line 57  my $irc_config = {
57          ircname => 'Anna the bot: try /msg irc-logger help',          ircname => 'Anna the bot: try /msg irc-logger help',
58  };  };
59    
 my $queue_dir = './queue';  
   
60  my $HOSTNAME = `hostname -f`;  my $HOSTNAME = `hostname -f`;
61  chomp($HOSTNAME);  chomp($HOSTNAME);
62    
# Line 81  if ( $HOSTNAME =~ m/llin/ ) { Line 78  if ( $HOSTNAME =~ m/llin/ ) {
78    
79  my @channels = ( $CHANNEL );  my @channels = ( $CHANNEL );
80    
81  warn "# config = ", dump( $irc_config ), $/;  warn "## config = ", dump( $irc_config ) if $debug;
82    
83  my $NICK = $irc_config->{nick} or die "no nick?";  my $NICK = $irc_config->{nick} or die "no nick?";
84    
# Line 112  my $log_path; Line 109  my $log_path;
109  GetOptions(  GetOptions(
110          'import-dircproxy:s' => \$import_dircproxy,          'import-dircproxy:s' => \$import_dircproxy,
111          'log:s' => \$log_path,          'log:s' => \$log_path,
112          'queue:s' => \$queue_dir,          'debug!' => \$debug,
113  );  );
114    
115  #$SIG{__DIE__} = sub {  #$SIG{__DIE__} = sub {
# Line 125  sub _log { Line 122  sub _log {
122    
123  open(STDOUT, '>', $log_path) && warn "log to $log_path: $!\n";  open(STDOUT, '>', $log_path) && warn "log to $log_path: $!\n";
124    
 # queue  
   
 if ( ! -d $queue_dir ) {  
         warn "## creating queue directory $queue_dir";  
         mkdir $queue_dir or die "can't create queue directory $queue_dir: $!";  
 }  
   
 my $dq = IPC::DirQueue->new({ dir => $queue_dir });  
125    
126  # HTML formatters  # HTML formatters
127    
# Line 616  sub save_message { Line 605  sub save_message {
605          $a->{me} ||= 0;          $a->{me} ||= 0;
606          $a->{time} ||= strftime($TIMESTAMP,localtime());          $a->{time} ||= strftime($TIMESTAMP,localtime());
607    
608          _log          _log "ARCHIVE",
609                  $a->{channel}, " ",                  $a->{channel}, " ",
610                  $a->{me} ? "***" . $a->{nick} : "<" . $a->{nick} . ">",                  $a->{me} ? "***" . $a->{nick} : "<" . $a->{nick} . ">",
611                  " " . $a->{message};                  " " . $a->{message};
612    
613          $sth_insert_log->execute($a->{channel}, $a->{me}, $a->{nick}, $a->{message}, $a->{time});          eval { $sth_insert_log->execute($a->{channel}, $a->{me}, $a->{nick}, $a->{message}, $a->{time}); };
614            _log "ERROR: can't archive ", $a->{message} if $@;
615          add_tag( id => $dbh->last_insert_id(undef,undef,"log",undef), %$a );          add_tag( id => $dbh->last_insert_id(undef,undef,"log",undef), %$a );
616  }  }
617    
# Line 666  if ($import_dircproxy) { Line 656  if ($import_dircproxy) {
656    
657  my $_stat;  my $_stat;
658    
659    POE::Component::Client::HTTP->spawn(
660            Alias   => 'rss-fetch',
661            Timeout => 30,
662    );
663    
664    =head2 rss_parse_xml
665    
666      rss_parse_xml({
667            url => 'http://www.example.com/rss',
668            send_rss_msgs => 42,
669      });
670    
671    =cut
672    
673  sub rss_fetch {  sub rss_parse_xml {
674          my ($args) = @_;          my ($kernel,$args) = @_;
675    
676            warn "## rss_parse_xml ",dump( $args ) if $debug;
677    
678          # how many messages to send out when feed is seen for the first time?          # how many messages to send out when feed is seen for the first time?
679          my $send_rss_msgs = 1;          my $send_rss_msgs = $args->{send_rss_msgs};
680            $send_rss_msgs = 1 if ! defined $send_rss_msgs;
681    
682          _log "RSS fetch", $args->{url};          warn "## RSS fetch first $send_rss_msgs items from", $args->{url} if $debug;
683    
684          my $feed = XML::Feed->parse(URI->new( $args->{url} ));          my $feed = XML::Feed->parse( \$args->{xml} );
685          if ( ! $feed ) {          if ( ! $feed ) {
686                  _log("can't fetch RSS ", $args->{url});                  _log "can't fetch RSS ", $args->{url}, XML::Feed->errstr;
687                  return;                  return;
688          }          }
689    
# Line 688  sub rss_fetch { Line 693  sub rss_fetch {
693          for my $entry ($feed->entries) {          for my $entry ($feed->entries) {
694                  $total++;                  $total++;
695    
696                    my $seen_times = $_stat->{rss}->{seen}->{$args->{channel}}->{$feed->link}->{$entry->id}++;
697                  # seen allready?                  # seen allready?
698                  next if $_stat->{rss}->{seen}->{$args->{channel}}->{$feed->link}->{$entry->id}++ > 0;                  warn "## $seen_times ",$entry->id if $debug;
699                    next if $seen_times > 0;
700    
701                  sub prefix {                  sub prefix {
702                          my ($txt,$var) = @_;                          my ($txt,$var) = @_;
# Line 715  sub rss_fetch { Line 722  sub rss_fetch {
722                  $msg .= prefix( ' | ' , $entry->title );                  $msg .= prefix( ' | ' , $entry->title );
723                  $msg .= prefix( ' | ' , $link );                  $msg .= prefix( ' | ' , $link );
724  #               $msg .= prefix( ' id ' , $entry->id );  #               $msg .= prefix( ' id ' , $entry->id );
725                    my @categories = $entry->category;
726                    warn "## category = ", dump( @categories ) if $debug;
727                  if ( my $tags = $entry->category ) {                  if ( my $tags = $entry->category ) {
728                            $tags = join(' ', @$tags) if ref($tags) eq 'ARRAY';
729                          $tags =~ s!^\s+!!;                          $tags =~ s!^\s+!!;
730                          $tags =~ s!\s*$! !;                          $tags =~ s!\s*$! !;
731                          $tags =~ s!,?\s+!// !g;                          $tags =~ s!,?\s+!// !g;
732                          $msg .= prefix( ' ' , $tags );                          $msg .= prefix( ' ' , $tags );
733                  }                  }
734    
735                  if ( $args->{kernel} && $send_rss_msgs ) {                  if ( $seen_times == 0 && $send_rss_msgs ) {
736                          $send_rss_msgs--;                          $send_rss_msgs--;
737                          if ( ! $args->{private} ) {                          if ( ! $args->{private} ) {
738                                  # FIXME bug! should be save_message                                  # FIXME bug! should be save_message
# Line 732  sub rss_fetch { Line 742  sub rss_fetch {
742                          my ( $type, $to ) = ( 'notice', $args->{channel} );                          my ( $type, $to ) = ( 'notice', $args->{channel} );
743                          ( $type, $to ) = ( 'privmsg', $args->{nick} ) if $args->{private};                          ( $type, $to ) = ( 'privmsg', $args->{nick} ) if $args->{private};
744    
745                          _log(">> $type $to", $msg);                          _log(">> RSS $type to $to:", $msg);
746  #                       $args->{kernel}->post( $irc => $type => $to, $msg );                          $kernel->post( $irc => $type => $to => $msg );
                         # XXX enqueue message to send later  
                         sub enqueue_post {  
                                 my $post = dump( @_ );  
                                 warn "## queue_post $post\n" if $debug;  
                                 $dq->enqueue_string( $post );  
                         }  
                         enqueue_post( $type => $to => $msg );  
747    
748                          $updates++;                          $updates++;
749                  }                  }
# Line 751  sub rss_fetch { Line 754  sub rss_fetch {
754          $sql .= qq{where id = } . $args->{id};          $sql .= qq{where id = } . $args->{id};
755          eval { $dbh->do( $sql ) };          eval { $dbh->do( $sql ) };
756    
757          _log "RSS got $total items of which $updates new";          _log "RSS $updates/$total new items from", $args->{url};
758    
759          return $updates;          return $updates;
760  }  }
761    
762  sub rss_fetch_all {  sub rss_fetch_all {
763          my $kernel = shift;          my ( $kernel, $send_rss_msgs )  = @_;
764            warn "## rss_fetch_all -- send_rss_msgs: $send_rss_msgs\n" if $debug;
765          my $sql = qq{          my $sql = qq{
766                  select id, url, name, channel, nick, private                  select id, url, name, channel, nick, private
767                  from feeds                  from feeds
768                  where active is true                  where active is true
769          };          };
770          # limit to newer feeds only if we are not sending messages out          # limit to newer feeds only if we are not sending messages out
771          $sql .= qq{     and last_update + delay < now() } if $kernel;          $sql .= qq{     and last_update + delay < now() } if defined ( $_stat->{rss}->{fetch} );
772          my $sth = $dbh->prepare( $sql );          my $sth = $dbh->prepare( $sql );
773          $sth->execute();          $sth->execute();
774          warn "# ",$sth->rows," active RSS feeds\n";          warn "# ",$sth->rows," active RSS feeds\n";
775          my $count = 0;          my $count = 0;
776          while (my $row = $sth->fetchrow_hashref) {          while (my $row = $sth->fetchrow_hashref) {
777                  $row->{kernel} = $kernel if $kernel;                  $row->{send_rss_msgs} = $send_rss_msgs if defined $send_rss_msgs;
778                  $count += rss_fetch( $row );                  $_stat->{rss}->{fetch}->{ $row->{url} } = $row;
779                    $kernel->post(
780                            'rss-fetch',
781                            'request',
782                            'rss_response',
783                            HTTP::Request->new( GET => $row->{url} ),
784                    );
785                    warn "## queued rss-fetch ", dump( $row ) if $debug;
786          }          }
787          return "OK, fetched $count posts from " . $sth->rows . " feeds";          return "OK, scheduled " . $sth->rows . " feeds for refresh";
788  }  }
789    
790    
# Line 786  sub rss_check_updates { Line 797  sub rss_check_updates {
797                  $_stat->{rss}->{last_poll} = time();                  $_stat->{rss}->{last_poll} = time();
798                  _log rss_fetch_all( $kernel );                  _log rss_fetch_all( $kernel );
799          }          }
         # XXX send queue messages  
         while ( my $job = $dq->pickup_queued_job() ) {  
                 my $data = read_file( $job->get_data_path ) || die "can't load ", $job->get_data_path, ": $!";  
 #               $kernel->post( $irc => $type => $to, $msg );  
                 my @data = eval $data;  
                 _log ">> post from queue ", $irc, @data;  
                 $kernel->post( $irc => @data );  
                 $job->finish;  
                 warn "## done queued job: ",dump( @data ) if $debug;  
         }  
800  }  }
801    
802  # seed rss seen cache so we won't send out all items on startup  sub process_command {
803  _log rss_fetch_all if ! $debug;          my ( $kernel, $nick, $channel, $msg ) = @_;
804    
805            my $res = "unknown command '$msg', try /msg $NICK help!";
806    
807            if ($msg =~ m/^help/i) {
808    
809                    $res = "usage: /msg $NICK comand | commands: stat - user/message stat | last - show backtrace | grep foobar - find foobar";
810    
811            } elsif ($msg =~ m/^(privmsg|notice)\s+(\S+)\s+(.*)$/i) {
812    
813                    _log ">> /$1 $2 $3";
814                    $kernel->post( $irc => $1 => $2, $3 );
815                    $res = '';
816    
817            } elsif ($msg =~ m/^stat.*?\s*(\d*)/i) {
818    
819                    my $nr = $1 || 10;
820    
821                    my $sth = $dbh->prepare(qq{
822                            select
823                                    trim(both '_' from nick) as nick,
824                                    count(*) as count,
825                                    sum(length(message)) as len
826                            from log
827                            group by trim(both '_' from nick)
828                            order by len desc,count desc
829                            limit $nr
830                    });
831                    $sth->execute();
832                    $res = "Top $nr users: ";
833                    my @users;
834                    while (my $row = $sth->fetchrow_hashref) {
835                            push @users,$row->{nick} . ': ' . $row->{count} . '/' . $row->{len} . '=' . sprintf("%.2f", $row->{len}/$row->{count});
836                    }
837                    $res .= join(" | ", @users);
838            } elsif ($msg =~ m/^last.*?\s*(\d*)/i) {
839    
840                    my $limit = $1 || meta( $nick, $channel, 'last-size' ) || 10;
841    
842                    foreach my $res (get_from_log( limit => $limit )) {
843                            _log "last: $res";
844                            $kernel->post( $irc => privmsg => $nick, $res );
845                    }
846    
847                    $res = '';
848    
849            } elsif ($msg =~ m/^(search|grep)\s+(.*)\s*$/i) {
850    
851                    my $what = $2;
852    
853                    foreach my $res (get_from_log(
854                                    limit => 20,
855                                    search => $what,
856                            )) {
857                            _log "search [$what]: $res";
858                            $kernel->post( $irc => privmsg => $nick, $res );
859                    }
860    
861                    $res = '';
862    
863            } elsif ($msg =~ m/^(?:count|poll)\s+(.*)(?:\s+(\d+))?\s*$/i) {
864    
865                    my ($what,$limit) = ($1,$2);
866                    $limit ||= 100;
867    
868                    my $stat;
869    
870                    foreach my $res (get_from_log(
871                                    limit => $limit,
872                                    search => $what,
873                                    full_rows => 1,
874                            )) {
875                            while ($res->{message} =~ s/\Q$what\E(\+|\-)//) {
876                                    $stat->{vote}->{$1}++;
877                                    $stat->{from}->{ $res->{nick} }++;
878                            }
879                    }
880    
881                    my @nicks;
882                    foreach my $nick (sort { $stat->{from}->{$a} <=> $stat->{from}->{$b} } keys %{ $stat->{from} }) {
883                            push @nicks, $nick . ( $stat->{from}->{$nick} == 1 ? '' :
884                                    "(" . $stat->{from}->{$nick} . ")"
885                            );
886                    }
887    
888                    $res =
889                            "$what ++ " . ( $stat->{vote}->{'+'} || 0 ) .
890                            " : " . ( $stat->{vote}->{'-'} || 0 ) . " --" .
891                            " from " . ( join(", ", @nicks) || 'nobody' );
892    
893                    $kernel->post( $irc => notice => $nick, $res );
894    
895            } elsif ($msg =~ m/^ping/) {
896                    $res = "ping = " . dump( $_stat->{ping} );
897            } elsif ($msg =~ m/^conf(?:ig)*\s*(last-size|twitter)*\s*(.*)/) {
898                    if ( ! defined( $1 ) ) {
899                            my $sth = $dbh->prepare(qq{ select name,value,changed from meta where nick = ? and channel = ? });
900                            $sth->execute( $nick, $channel );
901                            $res = "config for $nick on $channel";
902                            while ( my ($n,$v) = $sth->fetchrow_array ) {
903                                    $res .= " | $n = $v";
904                            }
905                    } elsif ( ! $2 ) {
906                            my $val = meta( $nick, $channel, $1 );
907                            $res = "current $1 = " . ( $val ? $val : 'undefined' );
908                    } else {
909                            my $validate = {
910                                    'last-size' => qr/^\d+/,
911                                    'twitter' => qr/^\w+\s+\w+/,
912                            };
913    
914                            my ( $op, $val ) = ( $1, $2 );
915    
916                            if ( my $regex = $validate->{$op} ) {
917                                    if ( $val =~ $regex ) {
918                                            meta( $nick, $channel, $op, $val );
919                                            $res = "saved $op = $val";
920                                    } else {
921                                            $res = "config option $op = $val doesn't validate against $regex";
922                                    }
923                            } else {
924                                    $res = "config option $op doesn't exist";
925                            }
926                    }
927            } elsif ($msg =~ m/^rss-update/) {
928                    $res = rss_fetch_all( $kernel );
929            } elsif ($msg =~ m/^rss-list/) {
930                    my $sth = $dbh->prepare(qq{ select url,name,last_update,active,channel,nick,private from feeds });
931                    $sth->execute;
932                    while (my @row = $sth->fetchrow_array) {
933                            $kernel->post( $irc => privmsg => $nick, join(' | ',@row) );
934                    }
935                    $res = '';
936            } elsif ($msg =~ m!^rss-(add|remove|stop|start|clean)(?:-(private))?\s+(http://\S+)\s*(.*)!) {
937                    my ( $command, $sub, $url, $arg ) = ( $1,$2,$3,$4 );
938    
939                    my $channel = $1 if ( $arg =~ s/\s*(#\S+)\s*// );
940                    $channel = $nick if $sub eq 'private';
941    
942                    my $sql = {
943                            add     => qq{ insert into feeds (url,name,channel,nick,private) values (?,?,?,?,?) },
944                            remove  => qq{ delete from feeds                                where url = ? and nick = ? },
945                            start   => qq{ update feeds set active = true   where url = ? },
946                            stop    => qq{ update feeds set active = false  where url = ? },
947                            clean   => qq{ update feeds set last_update = now() - delay where url = ? },
948                    };
949    
950                    if ( $command eq 'add' && ! $channel ) {
951                            $res = "ERROR: got '$msg' which doesn't have #channel in it, ignoring!";
952                    } elsif (my $q = $sql->{$command} ) {
953                            my $sth = $dbh->prepare( $q );
954                            my @data = ( $url );
955                            if ( $command eq 'add' ) {
956                                    push @data, ( $arg, $channel, $nick, $sub eq 'private' ? 1 : 0 );
957                            } elsif ( $command eq 'remove' ) {
958                                    push @data, $nick;
959                            }
960                            warn "## $command SQL $q with ",dump( @data ),"\n";
961                            eval { $sth->execute( @data ) };
962                            if ($@) {
963                                    $res = "ERROR: $@";
964                            } else {
965                                    $res = "OK, RSS executed $command" .
966                                            ( $sub ? "-$sub " : ' ' ) .
967                                            ( $channel ? "on $channel " : '' ) .
968                                            "url $url";
969                                    if ( $command eq 'clean' ) {
970                                            my $seen = $_stat->{rss}->{seen} || die "no seen?";
971                                            my $want_link = $_stat->{rss}->{url2link}->{$url} || warn "no url2link($url)";
972                                            foreach my $c ( keys %$seen ) {
973                                                    my $c_hash = $seen->{$c} || die "no seen->{$c}";
974                                                    die "not HASH with rss links but ", dump($c_hash) unless ref($c_hash) eq 'HASH';
975                                                    foreach my $link ( keys %$c_hash ) {
976                                                            next unless $link eq $want_link;
977                                                            _log "RSS removed seen $c $url $link";
978                                                    }
979                                            }
980                                    } elsif ( $command eq 'add' ) {
981                                            rss_fetch_all( $kernel );
982                                    }
983                            }
984                    } else {
985                            $res = "ERROR: don't know what to do with: $msg";
986                    }
987            } elsif ($msg =~ m/^rss-clean/) {
988                    # this makes sense because we didn't catch rss-clean http://... before!
989                    $_stat->{rss} = undef;
990                    $dbh->do( qq{ update feeds set last_update = now() - delay } );
991                    $res = rss_fetch_all( $kernel );
992            }
993    
994            return $res;
995    }
996    
997  POE::Session->create( inline_states => {  POE::Session->create( inline_states => {
998          _start => sub {                _start => sub {      
# Line 811  POE::Session->create( inline_states => { Line 1004  POE::Session->create( inline_states => {
1004                  my $poco_object = $sender->get_heap();                  my $poco_object = $sender->get_heap();
1005                  _log "connected to",$poco_object->server_name();                  _log "connected to",$poco_object->server_name();
1006                  $kernel->post( $sender => join => $_ ) for @channels;                  $kernel->post( $sender => join => $_ ) for @channels;
1007                    # seen RSS cache, so don't send out messages
1008                    _log rss_fetch_all( $kernel, 0 );
1009                  undef;                  undef;
1010          },          },
1011      irc_255 => sub {    # server is done blabbing  #       irc_255 => sub {        # server is done blabbing
1012                  $_[KERNEL]->post( $irc => join => $CHANNEL);  #               $_[KERNEL]->post( $irc => join => $CHANNEL);
1013      },  #       },
1014      irc_public => sub {      irc_public => sub {
1015                  my $kernel = $_[KERNEL];                  my $kernel = $_[KERNEL];
1016                  my $nick = (split /!/, $_[ARG0])[0];                  my $nick = (split /!/, $_[ARG0])[0];
# Line 863  POE::Session->create( inline_states => { Line 1058  POE::Session->create( inline_states => {
1058          irc_msg => sub {          irc_msg => sub {
1059                  my $kernel = $_[KERNEL];                  my $kernel = $_[KERNEL];
1060                  my $nick = (split /!/, $_[ARG0])[0];                  my $nick = (split /!/, $_[ARG0])[0];
                 my $msg = $_[ARG2];  
1061                  my $channel = $_[ARG1]->[0];                  my $channel = $_[ARG1]->[0];
1062                    my $msg = $_[ARG2];
1063                  warn "# ARG = ",dump( @_[ARG0,ARG1,ARG2] ) if $debug;                  warn "# ARG = ",dump( @_[ARG0,ARG1,ARG2] ) if $debug;
1064    
                 my $res = "unknown command '$msg', try /msg $NICK help!";  
                 my @out;  
   
1065                  _log "<< $msg";                  _log "<< $msg";
1066    
1067                  if ($msg =~ m/^help/i) {                  my $res = process_command( $_[KERNEL], $nick, $channel, $msg );
   
                         $res = "usage: /msg $NICK comand | commands: stat - user/message stat | last - show backtrace | grep foobar - find foobar";  
   
                 } elsif ($msg =~ m/^(privmsg|notice)\s+(\S+)\s+(.*)$/i) {  
   
                         _log ">> /$1 $2 $3";  
                         $_[KERNEL]->post( $irc => $1 => $2, $3 );  
                         $res = '';  
   
                 } elsif ($msg =~ m/^stat.*?\s*(\d*)/i) {  
   
                         my $nr = $1 || 10;  
   
                         my $sth = $dbh->prepare(qq{  
                                 select  
                                         trim(both '_' from nick) as nick,  
                                         count(*) as count,  
                                         sum(length(message)) as len  
                                 from log  
                                 group by trim(both '_' from nick)  
                                 order by len desc,count desc  
                                 limit $nr  
                         });  
                         $sth->execute();  
                         $res = "Top $nr users: ";  
                         my @users;  
                         while (my $row = $sth->fetchrow_hashref) {  
                                 push @users,$row->{nick} . ': ' . $row->{count} . '/' . $row->{len} . '=' . sprintf("%.2f", $row->{len}/$row->{count});  
                         }  
                         $res .= join(" | ", @users);  
                 } elsif ($msg =~ m/^last.*?\s*(\d*)/i) {  
   
                         my $limit = $1 || meta( $nick, $channel, 'last-size' ) || 10;  
   
                         foreach my $res (get_from_log( limit => $limit )) {  
                                 _log "last: $res";  
                                 $_[KERNEL]->post( $irc => privmsg => $nick, $res );  
                         }  
   
                         $res = '';  
   
                 } elsif ($msg =~ m/^(search|grep)\s+(.*)\s*$/i) {  
   
                         my $what = $2;  
   
                         foreach my $res (get_from_log(  
                                         limit => 20,  
                                         search => $what,  
                                 )) {  
                                 _log "search [$what]: $res";  
                                 $_[KERNEL]->post( $irc => privmsg => $nick, $res );  
                         }  
   
                         $res = '';  
   
                 } elsif ($msg =~ m/^(?:count|poll)\s+(.*)(?:\s+(\d+))?\s*$/i) {  
   
                         my ($what,$limit) = ($1,$2);  
                         $limit ||= 100;  
   
                         my $stat;  
   
                         foreach my $res (get_from_log(  
                                         limit => $limit,  
                                         search => $what,  
                                         full_rows => 1,  
                                 )) {  
                                 while ($res->{message} =~ s/\Q$what\E(\+|\-)//) {  
                                         $stat->{vote}->{$1}++;  
                                         $stat->{from}->{ $res->{nick} }++;  
                                 }  
                         }  
   
                         my @nicks;  
                         foreach my $nick (sort { $stat->{from}->{$a} <=> $stat->{from}->{$b} } keys %{ $stat->{from} }) {  
                                 push @nicks, $nick . ( $stat->{from}->{$nick} == 1 ? '' :  
                                         "(" . $stat->{from}->{$nick} . ")"  
                                 );  
                         }  
   
                         $res =  
                                 "$what ++ " . ( $stat->{vote}->{'+'} || 0 ) .  
                                 " : " . ( $stat->{vote}->{'-'} || 0 ) . " --" .  
                                 " from " . ( join(", ", @nicks) || 'nobody' );  
   
                         $_[KERNEL]->post( $irc => notice => $nick, $res );  
   
                 } elsif ($msg =~ m/^ping/) {  
                         $res = "ping = " . dump( $_stat->{ping} );  
                 } elsif ($msg =~ m/^conf(?:ig)*\s*(last-size|twitter)*\s*(.*)/) {  
                         if ( ! defined( $1 ) ) {  
                                 my $sth = $dbh->prepare(qq{ select name,value,changed from meta where nick = ? and channel = ? });  
                                 $sth->execute( $nick, $channel );  
                                 $res = "config for $nick on $channel";  
                                 while ( my ($n,$v) = $sth->fetchrow_array ) {  
                                         $res .= " | $n = $v";  
                                 }  
                         } elsif ( ! $2 ) {  
                                 my $val = meta( $nick, $channel, $1 );  
                                 $res = "current $1 = " . ( $val ? $val : 'undefined' );  
                         } else {  
                                 my $validate = {  
                                         'last-size' => qr/^\d+/,  
                                         'twitter' => qr/^\w+\s+\w+/,  
                                 };  
   
                                 my ( $op, $val ) = ( $1, $2 );  
   
                                 if ( my $regex = $validate->{$op} ) {  
                                         if ( $val =~ $regex ) {  
                                                 meta( $nick, $channel, $op, $val );  
                                                 $res = "saved $op = $val";  
                                         } else {  
                                                 $res = "config option $op = $val doesn't validate against $regex";  
                                         }  
                                 } else {  
                                         $res = "config option $op doesn't exist";  
                                 }  
                         }  
                 } elsif ($msg =~ m/^rss-update/) {  
                         $res = rss_fetch_all( $_[KERNEL] );  
                 } elsif ($msg =~ m/^rss-list/) {  
                         my $sth = $dbh->prepare(qq{ select url,name,last_update,active,channel,nick,private from feeds });  
                         $sth->execute;  
                         while (my @row = $sth->fetchrow_array) {  
                                 $_[KERNEL]->post( $irc => privmsg => $nick, join(' | ',@row) );  
                         }  
                         $res = '';  
                 } elsif ($msg =~ m!^rss-(add|remove|stop|start|clean)(?:-(private))?\s+(http://\S+)\s*(.*)!) {  
                         my ( $command, $sub, $url, $arg ) = ( $1,$2,$3,$4 );  
   
                         my $channel = $1 if ( $arg =~ s/\s*(#\S+)\s*// );  
                         $channel = $nick if $sub eq 'private';  
   
                         my $sql = {  
                                 add     => qq{ insert into feeds (url,name,channel,nick,private) values (?,?,?,?,?) },  
 #                               remove  => qq{ delete from feeds                                where url = ? and name = ? },  
                                 start   => qq{ update feeds set active = true   where url = ? },  
                                 stop    => qq{ update feeds set active = false  where url = ? },  
                                 clean   => qq{ update feeds set last_update = now() - delay where url = ? },  
                         };  
   
                         if ( $command eq 'add' && ! $channel ) {  
                                 $res = "ERROR: got '$msg' which doesn't have #channel in it, ignoring!";  
                         } elsif (my $q = $sql->{$command} ) {  
                                 my $sth = $dbh->prepare( $q );  
                                 my @data = ( $url );  
                                 if ( $command eq 'add' ) {  
                                         push @data, ( $arg, $channel, $nick, $sub eq 'private' ? 1 : 0 );  
                                 }  
                                 warn "## $command SQL $q with ",dump( @data ),"\n";  
                                 eval { $sth->execute( @data ) };  
                                 if ($@) {  
                                         $res = "ERROR: $@";  
                                 } else {  
                                         $res = "OK, RSS executed $command " . ( $sub ? "-$sub" : '' ) ."on $channel url $url";  
                                         if ( $command eq 'clean' ) {  
                                                 my $seen = $_stat->{rss}->{seen} || die "no seen?";  
                                                 my $want_link = $_stat->{rss}->{url2link}->{$url} || warn "no url2link($url)";  
                                                 foreach my $c ( keys %$seen ) {  
                                                         my $c_hash = $seen->{$c} || die "no seen->{$c}";  
                                                         die "not HASH with rss links but ", dump($c_hash) unless ref($c_hash) eq 'HASH';  
                                                         foreach my $link ( keys %$c_hash ) {  
                                                                 next unless $link eq $want_link;  
                                                                 _log "RSS removed seen $c $url $link";  
                                                         }  
                                                 }  
                                         }  
                                 }  
                         } else {  
                                 $res = "ERROR: don't know what to do with: $msg";  
                         }  
                 } elsif ($msg =~ m/^rss-clean/) {  
                         # this makes sense because we didn't catch rss-clean http://... before!  
                         $_stat->{rss} = undef;  
                         $dbh->do( qq{ update feeds set last_update = now() - delay } );  
                         $res = "OK, cleaned RSS cache";  
                 }  
1068    
1069                  if ($res) {                  if ($res) {
1070                          _log ">> [$nick] $res";                          _log ">> [$nick] $res";
# Line 1122  POE::Session->create( inline_states => { Line 1136  POE::Session->create( inline_states => {
1136          },          },
1137      _child => sub {},      _child => sub {},
1138      _default => sub {      _default => sub {
1139                  _log sprintf "sID:%s %s %s",                  _log '_default SID:', $_[SESSION]->ID, $_[ARG0], dump( $_[ARG1] );
1140                          $_[SESSION]->ID, $_[ARG0],                  0; # false for signals
                         ref($_[ARG1]) eq "ARRAY"        ?       join(",", map { ref($_) eq "ARRAY" ? join(";", @{$_}) : $_ } @{ $_[ARG1] })     :  
                         $_[ARG1]                                        ?       $_[ARG1]                                        :  
                         "";  
       0;                        # false for signals  
1141      },      },
1142            rss_response => sub {
1143                    my ($request_packet, $response_packet) = @_[ARG0, ARG1];
1144                    my $request_object  = $request_packet->[0];
1145                    my $response_object = $response_packet->[0];
1146    
1147                    my $row = delete( $_stat->{rss}->{fetch}->{ $request_object->uri } );
1148                    if ( $row ) {
1149                            $row->{xml} = $response_object->content;
1150                            rss_parse_xml( $_[KERNEL], $row );
1151                    } else {
1152                            warn "## can't find rss->fetch for ", $request_object->uri;
1153                    }
1154            },
1155     },     },
1156    );    );
1157    
# Line 1407  sub root_handler { Line 1430  sub root_handler {
1430          <p>See <a href="/history">history</a> of all messages.</p>          <p>See <a href="/history">history</a> of all messages.</p>
1431          </body></html>};          </body></html>};
1432    
1433          $response->content( $html );          $response->content( decode('utf-8',$html) );
1434          warn "<< ", $request->method, " ", $request->uri, " created ", length($html), " bytes\n";          warn "<< ", $request->method, " ", $request->uri, " created ", length($html), " bytes\n";
1435          return RC_OK;          return RC_OK;
1436  }  }

Legend:
Removed from v.119  
changed lines
  Added in v.132

  ViewVC Help
Powered by ViewVC 1.1.26