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

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

  ViewVC Help
Powered by ViewVC 1.1.26