/[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 126 by dpavlin, Fri Mar 14 16:06:57 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  sub rss_fetch {  =cut
         my ($args) = @_;  
671    
672    sub rss_parse_xml {
673            my ($kernel,$args) = @_;
674    
675            warn "## rss_parse_xml ",dump( @_ ) 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 722  sub rss_fetch { Line 728  sub rss_fetch {
728                          $msg .= prefix( ' ' , $tags );                          $msg .= prefix( ' ' , $tags );
729                  }                  }
730    
731                  if ( $args->{kernel} && $send_rss_msgs ) {                  if ( $seen_times == 0 && $send_rss_msgs ) {
732                          $send_rss_msgs--;                          $send_rss_msgs--;
733                          if ( ! $args->{private} ) {                          if ( ! $args->{private} ) {
734                                  # FIXME bug! should be save_message                                  # FIXME bug! should be save_message
# Line 732  sub rss_fetch { Line 738  sub rss_fetch {
738                          my ( $type, $to ) = ( 'notice', $args->{channel} );                          my ( $type, $to ) = ( 'notice', $args->{channel} );
739                          ( $type, $to ) = ( 'privmsg', $args->{nick} ) if $args->{private};                          ( $type, $to ) = ( 'privmsg', $args->{nick} ) if $args->{private};
740    
741                          _log(">> $type $to", $msg);                          _log(">> RSS $type to $to:", $msg);
742  #                       $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 );  
743    
744                          $updates++;                          $updates++;
745                  }                  }
# Line 751  sub rss_fetch { Line 750  sub rss_fetch {
750          $sql .= qq{where id = } . $args->{id};          $sql .= qq{where id = } . $args->{id};
751          eval { $dbh->do( $sql ) };          eval { $dbh->do( $sql ) };
752    
753          _log "RSS got $total items of which $updates new";          _log "RSS $updates/$total new items from", $args->{url};
754    
755          return $updates;          return $updates;
756  }  }
757    
758  sub rss_fetch_all {  sub rss_fetch_all {
759          my $kernel = shift;          my ( $kernel, $send_rss_msgs )  = @_;
760            warn "## rss_fetch_all -- send_rss_msgs: $send_rss_msgs\n" if $debug;
761          my $sql = qq{          my $sql = qq{
762                  select id, url, name, channel, nick, private                  select id, url, name, channel, nick, private
763                  from feeds                  from feeds
764                  where active is true                  where active is true
765          };          };
766          # limit to newer feeds only if we are not sending messages out          # limit to newer feeds only if we are not sending messages out
767          $sql .= qq{     and last_update + delay < now() } if $kernel;          $sql .= qq{     and last_update + delay < now() } if defined ( $_stat->{rss}->{fetch} );
768          my $sth = $dbh->prepare( $sql );          my $sth = $dbh->prepare( $sql );
769          $sth->execute();          $sth->execute();
770          warn "# ",$sth->rows," active RSS feeds\n";          warn "# ",$sth->rows," active RSS feeds\n";
771          my $count = 0;          my $count = 0;
772          while (my $row = $sth->fetchrow_hashref) {          while (my $row = $sth->fetchrow_hashref) {
773                  $row->{kernel} = $kernel if $kernel;                  $row->{send_rss_msgs} = $send_rss_msgs if defined $send_rss_msgs;
774                  $count += rss_fetch( $row );                  $_stat->{rss}->{fetch}->{ $row->{url} } = $row;
775                    $kernel->post(
776                            'rss-fetch',
777                            'request',
778                            'rss_response',
779                            HTTP::Request->new( GET => $row->{url} ),
780                    );
781                    warn "## queued rss-fetch ", dump( $row ) if $debug;
782          }          }
783          return "OK, fetched $count posts from " . $sth->rows . " feeds";          return "OK, scheduled " . $sth->rows . " feeds for refresh";
784  }  }
785    
786    
# Line 786  sub rss_check_updates { Line 793  sub rss_check_updates {
793                  $_stat->{rss}->{last_poll} = time();                  $_stat->{rss}->{last_poll} = time();
794                  _log rss_fetch_all( $kernel );                  _log rss_fetch_all( $kernel );
795          }          }
         # 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;  
         }  
796  }  }
797    
 # seed rss seen cache so we won't send out all items on startup  
 _log rss_fetch_all if ! $debug;  
   
798  POE::Session->create( inline_states => {  POE::Session->create( inline_states => {
799          _start => sub {                _start => sub {      
800                  $_[KERNEL]->post( $irc => register => 'all' );                  $_[KERNEL]->post( $irc => register => 'all' );
# Line 811  POE::Session->create( inline_states => { Line 805  POE::Session->create( inline_states => {
805                  my $poco_object = $sender->get_heap();                  my $poco_object = $sender->get_heap();
806                  _log "connected to",$poco_object->server_name();                  _log "connected to",$poco_object->server_name();
807                  $kernel->post( $sender => join => $_ ) for @channels;                  $kernel->post( $sender => join => $_ ) for @channels;
808                    # seen RSS cache, so don't send out messages
809                    _log rss_fetch_all( $kernel, 0 );
810                  undef;                  undef;
811          },          },
812      irc_255 => sub {    # server is done blabbing  #       irc_255 => sub {        # server is done blabbing
813                  $_[KERNEL]->post( $irc => join => $CHANNEL);  #               $_[KERNEL]->post( $irc => join => $CHANNEL);
814      },  #       },
815      irc_public => sub {      irc_public => sub {
816                  my $kernel = $_[KERNEL];                  my $kernel = $_[KERNEL];
817                  my $nick = (split /!/, $_[ARG0])[0];                  my $nick = (split /!/, $_[ARG0])[0];
# Line 1028  POE::Session->create( inline_states => { Line 1024  POE::Session->create( inline_states => {
1024                                  if ($@) {                                  if ($@) {
1025                                          $res = "ERROR: $@";                                          $res = "ERROR: $@";
1026                                  } else {                                  } else {
1027                                          $res = "OK, RSS executed $command " . ( $sub ? "-$sub" : '' ) ."on $channel url $url";                                          $res = "OK, RSS executed $command" . ( $sub ? "-$sub" : '' ) ." on $channel url $url";
1028                                          if ( $command eq 'clean' ) {                                          if ( $command eq 'clean' ) {
1029                                                  my $seen = $_stat->{rss}->{seen} || die "no seen?";                                                  my $seen = $_stat->{rss}->{seen} || die "no seen?";
1030                                                  my $want_link = $_stat->{rss}->{url2link}->{$url} || warn "no url2link($url)";                                                  my $want_link = $_stat->{rss}->{url2link}->{$url} || warn "no url2link($url)";
# Line 1040  POE::Session->create( inline_states => { Line 1036  POE::Session->create( inline_states => {
1036                                                                  _log "RSS removed seen $c $url $link";                                                                  _log "RSS removed seen $c $url $link";
1037                                                          }                                                          }
1038                                                  }                                                  }
1039                                            } elsif ( $command eq 'add' ) {
1040                                                    rss_fetch_all( $_[KERNEL] );
1041                                          }                                          }
1042                                  }                                  }
1043                          } else {                          } else {
# Line 1049  POE::Session->create( inline_states => { Line 1047  POE::Session->create( inline_states => {
1047                          # this makes sense because we didn't catch rss-clean http://... before!                          # this makes sense because we didn't catch rss-clean http://... before!
1048                          $_stat->{rss} = undef;                          $_stat->{rss} = undef;
1049                          $dbh->do( qq{ update feeds set last_update = now() - delay } );                          $dbh->do( qq{ update feeds set last_update = now() - delay } );
1050                          $res = "OK, cleaned RSS cache";                          $res = rss_fetch_all( $_[KERNEL] );
1051                  }                  }
1052    
1053                  if ($res) {                  if ($res) {
# Line 1129  POE::Session->create( inline_states => { Line 1127  POE::Session->create( inline_states => {
1127                          "";                          "";
1128        0;                        # false for signals        0;                        # false for signals
1129      },      },
1130            rss_response => sub {
1131                    my ($request_packet, $response_packet) = @_[ARG0, ARG1];
1132                    my $request_object  = $request_packet->[0];
1133                    my $response_object = $response_packet->[0];
1134    
1135                    my $row = delete( $_stat->{rss}->{fetch}->{ $request_object->uri } );
1136                    if ( $row ) {
1137                            $row->{xml} = $response_object->content;
1138                            rss_parse_xml( $_[KERNEL], $row );
1139                    } else {
1140                            warn "## can't find rss->fetch for ", $request_object->uri;
1141                    }
1142            },
1143     },     },
1144    );    );
1145    
# Line 1407  sub root_handler { Line 1418  sub root_handler {
1418          <p>See <a href="/history">history</a> of all messages.</p>          <p>See <a href="/history">history</a> of all messages.</p>
1419          </body></html>};          </body></html>};
1420    
1421          $response->content( $html );          $response->content( decode('utf-8',$html) );
1422          warn "<< ", $request->method, " ", $request->uri, " created ", length($html), " bytes\n";          warn "<< ", $request->method, " ", $request->uri, " created ", length($html), " bytes\n";
1423          return RC_OK;          return RC_OK;
1424  }  }

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

  ViewVC Help
Powered by ViewVC 1.1.26