require 0.19 AnyEvent::Redis to have PubSub
[MQR.git] / scripts / mqr-irc-client.pl
1 #!/usr/bin/env perl
2 # This is a simple script that connects stdin/stdout with a client
3 # connection to an irc server. the command line arguments are:
4 #
5 # $ ./debug_console <nick> <server> <port>
6 #
7 use common::sense;
8 use IO::Handle;
9 use AnyEvent;
10 use AnyEvent::IRC::Client;
11 use AnyEvent::IRC::Util qw/mk_msg parse_irc_msg encode_ctcp/;
12 use AnyEvent::Redis;
13 use Data::Dump qw(dump);
14 use Carp qw(confess);
15
16 my $nick = $ENV{IRC_NICK} || die "IRC_NICK";
17 my $room = $ENV{IRC_ROOM} || die "IRC_ROOM";
18
19 warn "# $ENV{IRC_SERVER}:$ENV{IRC_PORT} $room $nick\n";
20
21 my $c = AnyEvent->condvar;
22 my $stdout = AnyEvent::Handle->new (fh => \*STDOUT);
23 my $con = new AnyEvent::IRC::Client;
24
25 my $sub = AnyEvent::Redis->new( host => $ENV{REDIS_HOST}, port => $ENV{REDIS_PORT}, on_error => sub { confess @_ } );
26
27 $sub->psubscribe( 'channel *', sub {
28         my ( $message, $from ) = @_;
29         return unless $from !~ m/\Q$nick\E/; # skip our messages
30         warn "#Q<< ",dump( $from, $message );
31         my ( undef, $channel, $user ) = split(/ /,$from,3);
32         $con->send_msg( 'PRIVMSG', $room => join(' ',$channel, $user, $message) );
33 });
34
35 $con->reg_cb (
36    connect => sub {
37       my ($con, $err) = @_;
38
39       if (defined $err) {
40          warn "Couldn't connect: $err\n";
41          $c->broadcast;
42       } else {
43          $stdout->push_write ("Connected!\n");
44       }
45
46       $con->register ($nick, $nick, $nick);
47    },
48    debug_recv => sub {
49       my ($con, $msg) = @_;
50       $stdout->push_write (
51          "< "
52          . mk_msg ($msg->{prefix}, $msg->{command}, @{$msg->{params}})
53          . "\n"
54       );
55
56                 if ( $msg->{command} eq 'PRIVMSG' ) {
57                         my $channel = join(' ', 'channel', $msg->{params}->[0], $msg->{prefix});
58                         my $pub = AnyEvent::Redis->new( host => $ENV{REDIS_HOST}, port => $ENV{REDIS_PORT}, on_error => sub { confess @_ } );
59                         $pub->publish( $channel, $msg->{params}->[1] );
60                 } elsif ( $msg->{command} eq 'MODE' ) {
61                         $con->send_srv( JOIN => $room );
62                 }
63    },
64    debug_send => sub {
65       my ($con, @msg) = @_;
66       $stdout->push_write (
67          "> " . mk_msg (undef, @msg) . "\n"
68       );
69 warn dump(@msg);
70    },
71    registered => sub {
72       my ($con) = @_;
73
74       my $stdin;
75       $stdin = AnyEvent::Handle->new (
76          fh => \*STDIN,
77          on_eof => sub {
78             warn "EOF on STDIN, disconnecting...\n";
79             $con->disconnect ("Console EOF");
80          },
81          on_error => sub {
82             warn "Error on STDIN: $!\n";
83          },
84          on_read => sub {
85             $stdin->push_read (line => sub {
86                my ($stdin, $line) = @_;
87
88                if ($line =~ /^!/) {
89                   my $r = eval $line;
90                   if ($@) {
91                      warn "eval error: $@\n";
92                   } else {
93                      $Data::Dumper::Terse = 1;
94                      $stdout->push_write ("result: " . dump($r));
95                   }
96                } else {
97                   my $msg = parse_irc_msg ($line);
98                   $con->send_msg ($msg->{command}, @{$msg->{params}});
99                }
100             });
101          }
102       );
103    },
104    disconnect => sub {
105       warn "disconnect: $_[1]!\n";
106       $c->broadcast
107    },
108 );
109
110 $con->ctcp_auto_reply('VERSION', ['VERSION', 'MQR-IRC:0.1:Perl']);
111
112 $con->connect ($ENV{IRC_SERVER}, $ENV{IRC_PORT} || 6667);
113
114 $c->wait;