root/trunk/plagger/bin/plagger-ircbot

Revision 1327 (checked in by miyagawa, 2 years ago)

refactored load_include and load_recipes to Plagger::ConfigLoader?

  • Property svn:executable set to *
  • Property svn:keywords set to Id Revision
Line 
1 #!/usr/bin/perl
2 use warnings;
3 use strict;
4
5 use FindBin;
6 use lib "$FindBin::Bin/../lib";
7
8 use Getopt::Long;
9 use List::Util qw(first);
10 use YAML;
11
12 use Plagger::ConfigLoader;
13
14 use POE qw(
15     Session
16     Component::IRC
17     Component::IKC::Server
18     Component::IKC::Specifier
19 );
20
21 sub msg (@) { print "[msg] ", "@_\n" }
22 sub err (@) { print "[err] ", "@_\n" }
23
24 my $path = "$FindBin::Bin/../config.yaml";
25 GetOptions("--config=s", \$path);
26 Getopt::Long::Configure("bundling"); # allows -c
27
28 msg "loading configuration $path";
29
30 my $loader = Plagger::ConfigLoader->new;
31 my $base_config = $loader->load($path);
32
33 $loader->load_include($base_config);
34 $loader->load_recipes($base_config);
35
36 my $plugin = first { $_->{module} eq 'Notify::IRC' } @{ $base_config->{plugins} }
37     or die "Can't find Notify::IRC config in $path";
38
39 my $config = $plugin->{config};
40
41 msg 'creating daemon component';
42 POE::Component::IKC::Server->spawn(
43     port => $config->{daemon_port} || 9999,
44     name => 'NotifyIRCBot',
45 );
46
47 msg 'creating irc component';
48 POE::Component::IRC->spawn( alias => 'bot' )
49     or die "Couldn't create IRC POE session: $!";
50
51 msg 'creating kernel session';
52 POE::Session->create(
53     inline_states => {
54         _start           => \&bot_start,
55         _stop            => \&bot_stop,
56         connect          => \&bot_connect,
57         irc_001          => \&bot_connected,
58         irc_372          => \&bot_motd,
59         irc_433          => \&bot_nick_taken,
60         irc_disconnected => \&bot_reconnect,
61         irc_error        => \&bot_reconnect,
62         irc_socketerr    => \&bot_reconnect,
63         autoping         => \&bot_do_autoping,
64         update           => \&update,
65         _default         => $ENV{DEBUG} ? \&bot_default : sub { },
66     }
67 );
68
69 msg 'starting the kernel';
70 POE::Kernel->run();
71 msg 'exiting';
72 exit 0;
73
74 sub bot_default
75 {
76     my ( $event, $args ) = @_[ ARG0 .. $#_ ];
77     err "unhandled $event";
78     err "  - $_" foreach @$args;
79     return 0;
80 }
81
82 sub update
83 {
84     my ( $kernel, $heap, $msg ) = @_[ KERNEL, HEAP, ARG0 ];
85     eval {
86         for my $channel (@{ $config->{server_channels} }) {
87             if ($config->{announce} =~ /action/i) {
88                 $kernel->post( bot => ctcp => $channel, "ACTION $msg");
89             } else {
90                 $kernel->post( bot => notice => $channel, $msg )
91             }
92         }
93     };
94     err "update error: $@" if $@;
95 }
96
97 sub bot_start
98 {
99     my ( $kernel, $heap ) = @_[ KERNEL, HEAP ];
100     msg "starting irc session";
101     $kernel->alias_set('notify_irc');
102     $kernel->call( IKC => publish => notify_irc => ['update'] );
103     $kernel->post( bot => register => 'all' );
104     $kernel->yield('connect');
105 }
106
107 sub bot_connect
108 {
109     my ( $kernel, $heap ) = @_[ KERNEL, HEAP ];
110     msg "attempting to connect to server";
111     $kernel->post(
112         bot => connect => {
113             Nick     => $config->{nickname},
114             Ircname  => $config->{ircname} || $config->{nickname},
115             Username => $ENV{USER},
116             Server   => $config->{server_host},
117             Port     => $config->{server_port} || 6667,
118             Password => $config->{server_password} || undef,
119         }
120     );
121 }
122
123 sub bot_stop
124 {
125     msg "stopping bot";
126 }
127
128 sub bot_connected
129 {
130     my ( $kernel, $heap ) = @_[ KERNEL, HEAP ];
131     foreach ( @{$config->{server_channels}} )
132     {
133         msg "joining channel $_";
134         $kernel->post( bot => join => $_ );
135         if ($config->{charset}) {
136             $kernel->post( bot => charset => $config->{charset} );
137         }
138     }
139 }
140
141 sub bot_motd
142 {
143     msg '[motd] ' . $_[ARG1];
144 }
145
146 sub bot_do_autoping
147 {
148     my ( $kernel, $heap ) = @_[ KERNEL, HEAP ];
149     $kernel->post( bot => userhost => $config->{nickname} )
150         unless $heap->{seen_traffic};
151     $heap->{seen_traffic} = 0;
152     $kernel->delay( autoping => 300 );
153 }
154
155 sub bot_reconnect
156 {
157     my ( $kernel, $heap ) = @_[ KERNEL, HEAP ];
158     err "reconnect: " . $_[ARG0];
159     $kernel->delay( autoping => undef );
160     $kernel->delay( connect  => 60 );
161 }
162
163 sub bot_nick_taken
164 {
165     my ( $kernel, $heap ) = @_[ KERNEL, HEAP ];
166     if ($config->{nick} !~ /\d$/) {
167         $config->{nick} .= 0;
168     } else {
169         substr( $config->{nick}, -1, 1 )++;
170     }
171     err 'nick taken, trying new nick ' . $config->{nick};
172     $kernel->post( bot => nick => $config->{nick} );
173     $heap->{seen_traffic} = 1;
174 }
Note: See TracBrowser for help on using the browser.