/[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 118 by dpavlin, Wed Mar 12 18:21:03 2008 UTC revision 125 by dpavlin, Fri Mar 14 15:26:33 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;
22    use File::Slurp;
23    use Encode;
24    
25  =head1 NAME  =head1 NAME
26    
# Line 47  log all conversation on irc channel Line 50  log all conversation on irc channel
50    
51  ## CONFIG  ## CONFIG
52    
53    my $debug = 0;
54    
55  my $irc_config = {  my $irc_config = {
56          nick => 'irc-logger',          nick => 'irc-logger',
57          server => 'irc.freenode.net',          server => 'irc.freenode.net',
# Line 54  my $irc_config = { Line 59  my $irc_config = {
59          ircname => 'Anna the bot: try /msg irc-logger help',          ircname => 'Anna the bot: try /msg irc-logger help',
60  };  };
61    
62    my $queue_dir = './queue';
63    
64  my $HOSTNAME = `hostname -f`;  my $HOSTNAME = `hostname -f`;
65  chomp($HOSTNAME);  chomp($HOSTNAME);
66    
# Line 75  if ( $HOSTNAME =~ m/llin/ ) { Line 82  if ( $HOSTNAME =~ m/llin/ ) {
82    
83  my @channels = ( $CHANNEL );  my @channels = ( $CHANNEL );
84    
85  warn "# config = ", dump( $irc_config ), $/;  warn "## config = ", dump( $irc_config ) if $debug;
86    
87  my $NICK = $irc_config->{nick} or die "no nick?";  my $NICK = $irc_config->{nick} or die "no nick?";
88    
# Line 106  my $log_path; Line 113  my $log_path;
113  GetOptions(  GetOptions(
114          'import-dircproxy:s' => \$import_dircproxy,          'import-dircproxy:s' => \$import_dircproxy,
115          'log:s' => \$log_path,          'log:s' => \$log_path,
116            'queue:s' => \$queue_dir,
117            'debug!' => \$debug,
118  );  );
119    
120  #$SIG{__DIE__} = sub {  #$SIG{__DIE__} = sub {
# Line 118  sub _log { Line 127  sub _log {
127    
128  open(STDOUT, '>', $log_path) && warn "log to $log_path: $!\n";  open(STDOUT, '>', $log_path) && warn "log to $log_path: $!\n";
129    
130    # queue
131    
132    if ( ! -d $queue_dir ) {
133            warn "## creating queue directory $queue_dir";
134            mkdir $queue_dir or die "can't create queue directory $queue_dir: $!";
135    }
136    
137    my $dq = IPC::DirQueue->new({ dir => $queue_dir });
138    
139  # HTML formatters  # HTML formatters
140    
141  my %escape = ('<'=>'&lt;', '>'=>'&gt;', '&'=>'&amp;', '"'=>'&quot;');  my %escape = ('<'=>'&lt;', '>'=>'&gt;', '&'=>'&amp;', '"'=>'&quot;');
# Line 600  sub save_message { Line 618  sub save_message {
618          $a->{me} ||= 0;          $a->{me} ||= 0;
619          $a->{time} ||= strftime($TIMESTAMP,localtime());          $a->{time} ||= strftime($TIMESTAMP,localtime());
620    
621          _log          _log "ARCHIVE",
622                  $a->{channel}, " ",                  $a->{channel}, " ",
623                  $a->{me} ? "***" . $a->{nick} : "<" . $a->{nick} . ">",                  $a->{me} ? "***" . $a->{nick} : "<" . $a->{nick} . ">",
624                  " " . $a->{message};                  " " . $a->{message};
# Line 650  if ($import_dircproxy) { Line 668  if ($import_dircproxy) {
668    
669  my $_stat;  my $_stat;
670    
671    POE::Component::Client::HTTP->spawn(
672            Alias   => 'rss-fetch',
673            Timeout => 30,
674    );
675    
676    =head2 rss_parse_xml
677    
678      rss_parse_xml({
679            url => 'http://www.example.com/rss',
680            send_rss_msgs => 42,
681      });
682    
683  sub rss_fetch {  =cut
684    
685    sub rss_parse_xml {
686          my ($args) = @_;          my ($args) = @_;
687    
688            warn "## rss_parse_xml ",dump( @_ ) if $debug;
689    
690          # 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?
691          my $send_rss_msgs = 1;          my $send_rss_msgs = $args->{send_rss_msgs};
692            $send_rss_msgs = 1 if ! defined $send_rss_msgs;
693    
694          _log "RSS fetch", $args->{url};          _log "RSS fetch first $send_rss_msgs items from", $args->{url};
695    
696          my $feed = XML::Feed->parse(URI->new( $args->{url} ));          my $feed = XML::Feed->parse( \$args->{xml} );
697          if ( ! $feed ) {          if ( ! $feed ) {
698                  _log("can't fetch RSS ", $args->{url});                  _log "can't fetch RSS ", $args->{url}, XML::Feed->errstr;
699                  return;                  return;
700          }          }
701    
# Line 671  sub rss_fetch { Line 705  sub rss_fetch {
705          for my $entry ($feed->entries) {          for my $entry ($feed->entries) {
706                  $total++;                  $total++;
707    
708                    my $seen_times = $_stat->{rss}->{seen}->{$args->{channel}}->{$feed->link}->{$entry->id}++;
709                  # seen allready?                  # seen allready?
710                  next if $_stat->{rss}->{seen}->{$args->{channel}}->{$feed->link}->{$entry->id}++ > 0;                  warn "## $seen_times ",$entry->id if $debug;
711                    next if $seen_times > 0;
712    
713                  sub prefix {                  sub prefix {
714                          my ($txt,$var) = @_;                          my ($txt,$var) = @_;
# Line 705  sub rss_fetch { Line 741  sub rss_fetch {
741                          $msg .= prefix( ' ' , $tags );                          $msg .= prefix( ' ' , $tags );
742                  }                  }
743    
744                  if ( $args->{kernel} && $send_rss_msgs ) {                  if ( $seen_times == 0 && $send_rss_msgs ) {
745                          $send_rss_msgs--;                          $send_rss_msgs--;
746                          if ( ! $args->{private} ) {                          if ( ! $args->{private} ) {
747                                  # FIXME bug! should be save_message                                  # FIXME bug! should be save_message
748  #                               save_message( channel => $args->{channel}, me => 1, nick => $NICK, message => $msg );                                  save_message( channel => $args->{channel}, me => 1, nick => $NICK, message => $msg );
749                                  $sth_insert_log->execute( $args->{channel}, 1, $NICK, $msg, 'now()' );  #                               $sth_insert_log->execute( $args->{channel}, 1, $NICK, $msg, 'now()' );
750                          }                          }
751                          my ( $type, $to ) = ( 'notice', $args->{channel} );                          my ( $type, $to ) = ( 'notice', $args->{channel} );
752                          ( $type, $to ) = ( 'privmsg', $args->{nick} ) if $args->{private};                          ( $type, $to ) = ( 'privmsg', $args->{nick} ) if $args->{private};
753                          _log(">> $type $to", $msg);  
754                          $args->{kernel}->post( $irc => $type => $to, $msg );                          _log("RSS generated $type to $to:", $msg);
755                            # XXX enqueue message to send later
756                            sub enqueue_post {
757                                    my $post = dump( @_ );
758                                    warn "## queue_post $post\n" if $debug;
759                                    $dq->enqueue_string( $post );
760                            }
761                            enqueue_post( $type => $to => $msg );
762    
763                          $updates++;                          $updates++;
764                  }                  }
765          }          }
# Line 725  sub rss_fetch { Line 769  sub rss_fetch {
769          $sql .= qq{where id = } . $args->{id};          $sql .= qq{where id = } . $args->{id};
770          eval { $dbh->do( $sql ) };          eval { $dbh->do( $sql ) };
771    
772          _log "RSS got $total items of which $updates new";          _log "RSS got $total items of which $updates new from", $args->{url};
773    
774          return $updates;          return $updates;
775  }  }
776    
777  sub rss_fetch_all {  sub rss_fetch_all {
778          my $kernel = shift;          my ( $kernel, $send_rss_msgs )  = @_;
779            warn "## rss_fetch_all -- send_rss_msgs: $send_rss_msgs\n" if $debug;
780          my $sql = qq{          my $sql = qq{
781                  select id, url, name, channel, nick, private                  select id, url, name, channel, nick, private
782                  from feeds                  from feeds
783                  where active is true                  where active is true
784          };          };
785          # limit to newer feeds only if we are not sending messages out          # limit to newer feeds only if we are not sending messages out
786          $sql .= qq{     and last_update + delay < now() } if $kernel;          $sql .= qq{     and last_update + delay < now() } if defined ( $_stat->{rss}->{fetch} );
787          my $sth = $dbh->prepare( $sql );          my $sth = $dbh->prepare( $sql );
788          $sth->execute();          $sth->execute();
789          warn "# ",$sth->rows," active RSS feeds\n";          warn "# ",$sth->rows," active RSS feeds\n";
790          my $count = 0;          my $count = 0;
791          while (my $row = $sth->fetchrow_hashref) {          while (my $row = $sth->fetchrow_hashref) {
792                  $row->{kernel} = $kernel if $kernel;                  $row->{send_rss_msgs} = $send_rss_msgs if defined $send_rss_msgs;
793                  $count += rss_fetch( $row );                  $_stat->{rss}->{fetch}->{ $row->{url} } = $row;
794                    $kernel->post(
795                            'rss-fetch',
796                            'request',
797                            'rss_response',
798                            HTTP::Request->new( GET => $row->{url} ),
799                    );
800                    warn "## queued rss-fetch ", dump( $row ) if $debug;
801          }          }
802          return "OK, fetched $count posts from " . $sth->rows . " feeds";          return "OK, scheduled " . $sth->rows . " feeds for refresh";
803  }  }
804    
805    
# Line 755  sub rss_check_updates { Line 807  sub rss_check_updates {
807          my $kernel = shift;          my $kernel = shift;
808          $_stat->{rss}->{last_poll} ||= time();          $_stat->{rss}->{last_poll} ||= time();
809          my $dt = time() - $_stat->{rss}->{last_poll};          my $dt = time() - $_stat->{rss}->{last_poll};
         warn "## rss_check_updates $dt > $rss_min_delay\n";  
810          if ( $dt > $rss_min_delay ) {          if ( $dt > $rss_min_delay ) {
811                    warn "## rss_check_updates $dt > $rss_min_delay\n";
812                  $_stat->{rss}->{last_poll} = time();                  $_stat->{rss}->{last_poll} = time();
813                  _log rss_fetch_all( $kernel );                  _log rss_fetch_all( $kernel );
814          }          }
815            # XXX send queue messages
816            while ( my $job = $dq->pickup_queued_job() ) {
817                    my $data = read_file( $job->get_data_path ) || die "can't load ", $job->get_data_path, ": $!";
818                    my @data = eval $data;
819                    _log "IRC post from queue:", @data;
820                    $kernel->post( $irc => @data );
821                    $job->finish;
822                    warn "## done queued job: ",dump( @data ) if $debug;
823            }
824  }  }
825    
 # seed rss seen cache so we won't send out all items on startup  
 _log rss_fetch_all;  
   
826  POE::Session->create( inline_states => {  POE::Session->create( inline_states => {
827          _start => sub {                _start => sub {      
828                  $_[KERNEL]->post( $irc => register => 'all' );                  $_[KERNEL]->post( $irc => register => 'all' );
# Line 775  POE::Session->create( inline_states => { Line 833  POE::Session->create( inline_states => {
833                  my $poco_object = $sender->get_heap();                  my $poco_object = $sender->get_heap();
834                  _log "connected to",$poco_object->server_name();                  _log "connected to",$poco_object->server_name();
835                  $kernel->post( $sender => join => $_ ) for @channels;                  $kernel->post( $sender => join => $_ ) for @channels;
836                    # seen RSS cache, so don't send out messages
837                    _log rss_fetch_all( $kernel, 0 );
838                  undef;                  undef;
839          },          },
840      irc_255 => sub {    # server is done blabbing  #       irc_255 => sub {        # server is done blabbing
841                  $_[KERNEL]->post( $irc => join => $CHANNEL);  #               $_[KERNEL]->post( $irc => join => $CHANNEL);
842      },  #       },
843      irc_public => sub {      irc_public => sub {
844                  my $kernel = $_[KERNEL];                  my $kernel = $_[KERNEL];
845                  my $nick = (split /!/, $_[ARG0])[0];                  my $nick = (split /!/, $_[ARG0])[0];
# Line 829  POE::Session->create( inline_states => { Line 889  POE::Session->create( inline_states => {
889                  my $nick = (split /!/, $_[ARG0])[0];                  my $nick = (split /!/, $_[ARG0])[0];
890                  my $msg = $_[ARG2];                  my $msg = $_[ARG2];
891                  my $channel = $_[ARG1]->[0];                  my $channel = $_[ARG1]->[0];
892                    warn "# ARG = ",dump( @_[ARG0,ARG1,ARG2] ) if $debug;
893    
894                  my $res = "unknown command '$msg', try /msg $NICK help!";                  my $res = "unknown command '$msg', try /msg $NICK help!";
895                  my @out;                  my @out;
# Line 1073  POE::Session->create( inline_states => { Line 1134  POE::Session->create( inline_states => {
1134                          _log ">> registreted, so IDENTIFY";                          _log ">> registreted, so IDENTIFY";
1135                          $_[KERNEL]->post( $irc => privmsg => 'nickserv', "IDENTIFY $NICK" );                          $_[KERNEL]->post( $irc => privmsg => 'nickserv', "IDENTIFY $NICK" );
1136                  } else {                  } else {
1137                          warn "## ignore $m\n";                          warn "## ignore $m\n" if $debug;
1138                  }                  }
1139          },          },
1140          irc_snotice => sub {          irc_snotice => sub {
# Line 1092  POE::Session->create( inline_states => { Line 1153  POE::Session->create( inline_states => {
1153                          "";                          "";
1154        0;                        # false for signals        0;                        # false for signals
1155      },      },
1156            rss_response => sub {
1157                    my ($request_packet, $response_packet) = @_[ARG0, ARG1];
1158                    my $request_object  = $request_packet->[0];
1159                    my $response_object = $response_packet->[0];
1160    
1161                    my $row = delete( $_stat->{rss}->{fetch}->{ $request_object->uri } );
1162                    if ( $row ) {
1163                            $row->{xml} = $response_object->content;
1164                            rss_parse_xml( $row );
1165                    } else {
1166                            warn "## can't find rss->fetch for ", $request_object->uri;
1167                    }
1168            },
1169     },     },
1170    );    );
1171    
# Line 1370  sub root_handler { Line 1444  sub root_handler {
1444          <p>See <a href="/history">history</a> of all messages.</p>          <p>See <a href="/history">history</a> of all messages.</p>
1445          </body></html>};          </body></html>};
1446    
1447          $response->content( $html );          $response->content( decode('utf-8',$html) );
1448          warn "<< ", $request->method, " ", $request->uri, " created ", length($html), " bytes\n";          warn "<< ", $request->method, " ", $request->uri, " created ", length($html), " bytes\n";
1449          return RC_OK;          return RC_OK;
1450  }  }

Legend:
Removed from v.118  
changed lines
  Added in v.125

  ViewVC Help
Powered by ViewVC 1.1.26