--- trunk/irc-logger.pl 2006/03/01 21:29:14 7 +++ trunk/irc-logger.pl 2006/03/12 14:36:12 14 @@ -18,11 +18,11 @@ ## CONFIG -my $NICK = 'irc-logger-dev'; +my $NICK = 'irc-logger'; my $CONNECT = {Server => 'irc.freenode.net', Nick => $NICK, - Ircname => 'logger: ask dpavlin@rot13.org' + Ircname => "try /msg $NICK help", }; my $CHANNEL = '#razmjenavjestina'; my $IRC_ALIAS = "log"; @@ -35,11 +35,14 @@ my $DSN = 'DBI:Pg:dbname=irc-logger'; +my $ENCODING = 'ISO-8859-2'; + ## END CONFIG -use POE qw(Component::IRC Wheel::FollowTail); +use POE qw(Component::IRC Wheel::FollowTail Component::Server::HTTP); +use HTTP::Status; use DBI; use Encode qw/from_to/; @@ -72,6 +75,104 @@ values (?,?,?) }); +=head2 get_from_log + + my @messages = get_from_log( + limit => 42, + search => '%what to stuff in ilike%', + fmt => { + time => '{%s} ', + time_channel => '{%s %s} ', + nick => '%s: ', + message => '%s', + }, + ); + +=cut + +sub get_from_log { + my $args = {@_}; + + $args->{limit} ||= 10; + + $args->{fmt} ||= { + time => '{%s} ', + time_channel => '{%s %s} ', + nick => '%s: ', + message => '%s', + }; + + my $sql = qq{ + select + time::date as date, + time::time as time, + channel, + nick, + message + from log + }; + $sql .= " where message ilike ? " if ($args->{search}); + $sql .= " order by log.time desc"; + $sql .= " limit " . $args->{limit}; + + my $sth = $dbh->prepare( $sql ); + if ($args->{search}) { + $sth->execute( $args->{search} ); + } else { + $sth->execute(); + } + my $last_row = { + date => '', + time => '', + channel => '', + nick => '', + }; + + my @rows; + + while (my $row = $sth->fetchrow_hashref) { + unshift @rows, $row; + } + + my @msgs; + + foreach my $row (@rows) { + + $row->{time} =~ s#\.\d+##; + + my $t; + $t = $row->{date} . ' ' if ($last_row->{date} ne $row->{date}); + $t .= $row->{time}; + + my $msg = ''; + + if ($last_row->{channel} ne $row->{channel}) { + $msg .= sprintf($args->{fmt}->{time_channel}, $t, $row->{channel}); + } else { + $msg .= sprintf($args->{fmt}->{time}, $t); + } + + my $append = 1; + + if ($last_row->{nick} ne $row->{nick}) { + $msg .= sprintf($args->{fmt}->{nick}, $row->{nick}); + $append = 0; + } + + $msg .= sprintf($args->{fmt}->{message}, $row->{message}); + + if ($append && @msgs) { + $msgs[$#msgs] .= " " . $msg; + } else { + push @msgs, $msg; + } + + $last_row = $row; + } + + return @msgs; +} + my $SKIPPING = 0; # if skipping, how many we've done my $SEND_QUEUE; # cache @@ -84,11 +185,12 @@ $_[KERNEL]->post($IRC_ALIAS => register => 'all'); $_[KERNEL]->post($IRC_ALIAS => connect => $CONNECT); }, - irc_255 => sub { # server is done blabbing + irc_255 => sub { # server is done blabbing $_[KERNEL]->post($IRC_ALIAS => join => $CHANNEL); $_[KERNEL]->post($IRC_ALIAS => join => '#logger'); $_[KERNEL]->yield("heartbeat"); # start heartbeat # $_[KERNEL]->yield("my_add", $_) for keys %FOLLOWS; + $_[KERNEL]->post( $IRC_ALIAS => privmsg => 'nickserv', "IDENTIFY $NICK" ); }, irc_public => sub { my $kernel = $_[KERNEL]; @@ -96,7 +198,7 @@ my $channel = $_[ARG1]->[0]; my $msg = $_[ARG2]; - from_to($msg, 'UTF-8', 'ISO-8859-2'); + from_to($msg, 'UTF-8', $ENCODING); print "$channel: <$nick> $msg\n"; $sth->execute($channel, $nick, $msg); @@ -105,13 +207,24 @@ my $kernel = $_[KERNEL]; my $nick = (split /!/, $_[ARG0])[0]; my $msg = $_[ARG2]; - from_to($msg, 'UTF-8', 'ISO-8859-2'); + from_to($msg, 'UTF-8', $ENCODING); - my $res = 'unknown command ' . $msg; + my $res = "unknown command '$msg', try /msg $NICK help!"; + my @out; print "<< $msg\n"; - if ($msg =~ m/^stat.*\s*(\d*)/) { + if ($msg =~ m/^help/i) { + + $res = "usage: /msg $NICK comand | commands: stat - user/message stat | last - show backtrace | grep foobar - find foobar"; + + } elsif ($msg =~ m/^msg\s+(\S+)\s+(.*)$/i) { + + print ">> /msg $1 $2\n"; + $_[KERNEL]->post( $IRC_ALIAS => privmsg => $1, $2 ); + $res = ''; + + } elsif ($msg =~ m/^stat.*?\s*(\d*)/i) { my $nr = $1 || 10; @@ -120,36 +233,79 @@ }); $sth->execute(); $res = "Top $nr users: "; + my @users; while (my $row = $sth->fetchrow_hashref) { - $res .= $row->{nick} . ': ' . $row->{count} . ", "; + push @users,$row->{nick} . ': ' . $row->{count}; + } + $res .= join(" | ", @users); + } elsif ($msg =~ m/^last.*?\s*(\d*)/i) { + + foreach my $res (get_from_log( limit => $1 )) { + print "last: $res\n"; + from_to($res, $ENCODING, 'UTF-8'); + $_[KERNEL]->post( $IRC_ALIAS => privmsg => $nick, $res ); } - } - $res =~ s/,\s*$//; - print ">> [$nick] $res\n"; + $res = ''; - from_to($res, 'ISO-8859-2', 'UTF-8'); - $_[KERNEL]->post( $IRC_ALIAS => privmsg => $nick, $res ); + } elsif ($msg =~ m/^(search|grep)\s+(.*)$/i) { + + my $what = $2; + + foreach my $res (get_from_log( limit => 20, search => "%${what}%" )) { + print "search [$what]: $res\n"; + from_to($res, $ENCODING, 'UTF-8'); + $_[KERNEL]->post( $IRC_ALIAS => privmsg => $nick, $res ); + } + + $res = ''; + + } + + if ($res) { + print ">> [$nick] $res\n"; + from_to($res, $ENCODING, 'UTF-8'); + $_[KERNEL]->post( $IRC_ALIAS => privmsg => $nick, $res ); + } }, + irc_477 => sub { + print "# irc_477: ",$_[ARG1], "\n"; + $_[KERNEL]->post( $IRC_ALIAS => privmsg => 'nickserv', "register $NICK" ); + }, irc_505 => sub { - print "# irc_505: ",$_[ARG1], "\n"; + print "# irc_505: ",$_[ARG1], "\n"; $_[KERNEL]->post( $IRC_ALIAS => privmsg => 'nickserv', "register $NICK" ); - warn "## register $NICK\n"; - $_[KERNEL]->post( $IRC_ALIAS => privmsg => 'nickserv', "IDENTIFY $NICK" ); +# $_[KERNEL]->post( $IRC_ALIAS => privmsg => 'nickserv', "set hide email on" ); +# $_[KERNEL]->post( $IRC_ALIAS => privmsg => 'nickserv', "set email dpavlin\@rot13.org" ); + }, + irc_registered => sub { warn "## indetify $NICK\n"; + $_[KERNEL]->post( $IRC_ALIAS => privmsg => 'nickserv', "IDENTIFY $NICK" ); + }, +# irc_433 => sub { +# print "# irc_433: ",$_[ARG1], "\n"; +# warn "## indetify $NICK\n"; +# $_[KERNEL]->post( $IRC_ALIAS => privmsg => 'nickserv', "IDENTIFY $NICK" ); +# }, + irc_372 => sub { + print "MOTD: ", $_[ARG1], "\n"; + }, + irc_snotice => sub { + print "(server notice): ", $_[ARG0], "\n"; }, (map { ;"irc_$_" => sub { }} - qw(join - ctcp_version - connected snotice ctcp_action ping notice mode part quit - 001 002 003 004 005 - 250 251 252 253 254 265 266 - 332 333 353 366 372 375 376 - 477 + qw( )), +# join +# ctcp_version +# connected snotice ctcp_action ping notice mode part quit +# 001 002 003 004 005 +# 250 251 252 253 254 265 266 +# 332 333 353 366 372 375 376 +# 477 _child => sub {}, _default => sub { printf "%s: session %s caught an unhandled %s event.\n", @@ -221,4 +377,41 @@ }, ); +# http server + +my $httpd = POE::Component::Server::HTTP->new( + Port => $NICK =~ m/-dev/ ? 8001 : 8000, + ContentHandler => { '/' => \&root_handler }, + Headers => { Server => 'irc-logger' }, +); + +my $style = <<'_END_OF_STYLE_'; +.time, .channel { color: #808080; font-size: 60%; } +.nick { color: #0000ff; font-size: 80%; } +.message { color: #000000; font-size: 100%; } +_END_OF_STYLE_ + +sub root_handler { + my ($request, $response) = @_; + $response->code(RC_OK); + $response->content_type("text/html; charset=$ENCODING"); + $response->content( + qq{$NICK} . + "irc-logger url: " . $request->uri . '
' . + join("
", + get_from_log( + limit => 100, + fmt => { + time => '%s ', + time_channel => '%s %s ', + nick => '%s: ', + message => '%s', + }, + ) + ) . + qq{} + ); + return RC_OK; +} + POE::Kernel->run;