line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package POE::Component::IRC::Plugin::CPAN::Info; |
2
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
246424
|
use warnings; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
38
|
|
4
|
1
|
|
|
1
|
|
6
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
43
|
|
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
our $VERSION = '1.001002'; # VERSION |
7
|
|
|
|
|
|
|
|
8
|
1
|
|
|
1
|
|
4
|
use Carp; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
76
|
|
9
|
1
|
|
|
1
|
|
6
|
use POE; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
9
|
|
10
|
1
|
|
|
1
|
|
460
|
use POE::Component::IRC::Plugin (qw( :ALL )); |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
160
|
|
11
|
1
|
|
|
1
|
|
1217
|
use POE::Component::CPAN::SQLite::Info; |
|
1
|
|
|
|
|
262222
|
|
|
1
|
|
|
|
|
4784
|
|
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
sub new { |
14
|
0
|
|
|
0
|
0
|
|
my $package = shift; |
15
|
0
|
|
|
|
|
|
my %args = @_; |
16
|
0
|
|
|
|
|
|
$args{ lc $_ } = delete $args{ $_ } for keys %args; |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
# load defaults and override with user args if any |
19
|
0
|
|
|
|
|
|
%args = ( |
20
|
|
|
|
|
|
|
mirror => 'http://cpan.perl.org/', |
21
|
|
|
|
|
|
|
path => 'cpan_sqlite_info', |
22
|
|
|
|
|
|
|
debug => 0, |
23
|
|
|
|
|
|
|
freshen_interval => 43200, |
24
|
|
|
|
|
|
|
got_info_event => 'cpaninfo_got_info', |
25
|
|
|
|
|
|
|
no_result_event => 'cpaninfo_no_result', |
26
|
|
|
|
|
|
|
response_event => 'cpaninfo_response', |
27
|
|
|
|
|
|
|
respond_no_result => 1, |
28
|
|
|
|
|
|
|
send_events => 1, |
29
|
|
|
|
|
|
|
show_help => 1, |
30
|
|
|
|
|
|
|
eat => 0, |
31
|
|
|
|
|
|
|
listen_for_help => [ qw(public notice privmsg) ], |
32
|
|
|
|
|
|
|
listen_for_input => [ qw(public notice privmsg) ], |
33
|
|
|
|
|
|
|
no_result_responses => [ 'No clue', 'No idea' ], |
34
|
|
|
|
|
|
|
max_modules_limit => 5, |
35
|
|
|
|
|
|
|
max_modules_length => 300, |
36
|
|
|
|
|
|
|
max_output_length => 600, |
37
|
|
|
|
|
|
|
max_output_length_pub => 400, |
38
|
|
|
|
|
|
|
output_line_length => 300, |
39
|
|
|
|
|
|
|
banned => [], |
40
|
|
|
|
|
|
|
%args, |
41
|
|
|
|
|
|
|
); |
42
|
|
|
|
|
|
|
|
43
|
0
|
|
|
|
|
|
for my $listen_type (qw( listen_for_help listen_for_input )) { |
44
|
0
|
|
|
|
|
|
$args{ $listen_type } = { |
45
|
0
|
|
|
|
|
|
map { lc $_ => 1 } |
46
|
0
|
|
|
|
|
|
@{ $args{ $listen_type } } |
47
|
|
|
|
|
|
|
}; |
48
|
|
|
|
|
|
|
} |
49
|
|
|
|
|
|
|
|
50
|
0
|
0
|
|
|
|
|
unless ( exists $args{ua_args}{timeout} ) { |
51
|
0
|
|
|
|
|
|
$args{ua_args}{timeout} = 30; |
52
|
|
|
|
|
|
|
} |
53
|
|
|
|
|
|
|
|
54
|
0
|
0
|
0
|
|
|
|
if ( exists $args{channels} and ref $args{channels} ne 'ARRAY' ) { |
55
|
0
|
|
|
|
|
|
carp "Argument `channels` must contain an arrayref.."; |
56
|
0
|
|
|
|
|
|
return; |
57
|
|
|
|
|
|
|
} |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
# assign default triggers to anything not specified by user. |
60
|
0
|
|
|
|
|
|
my $default_triggers_ref = _make_default_triggers(); |
61
|
0
|
0
|
|
|
|
|
if ( exists $args{triggers} ) { |
62
|
|
|
|
|
|
|
|
63
|
0
|
|
|
|
|
|
foreach my $trigger_category (qw( mod dist auth )) { |
64
|
0
|
|
|
|
|
|
my $cat_triggers = $default_triggers_ref->{ $trigger_category}; |
65
|
|
|
|
|
|
|
|
66
|
0
|
0
|
|
|
|
|
$args{triggers}{ $trigger_category } = { |
67
|
|
|
|
|
|
|
%$cat_triggers, |
68
|
0
|
|
|
|
|
|
%{ $args{triggers}{ $trigger_category } || {} }, |
69
|
|
|
|
|
|
|
}; |
70
|
|
|
|
|
|
|
|
71
|
0
|
|
|
|
|
|
my $cat_trigger = "${trigger_category}_cat"; |
72
|
0
|
0
|
|
|
|
|
unless ( exists $args{triggers}{ $cat_trigger } ) { |
73
|
0
|
|
|
|
|
|
$args{trigger}{ $cat_trigger } |
74
|
|
|
|
|
|
|
= $default_triggers_ref->{ $cat_trigger}; |
75
|
|
|
|
|
|
|
} |
76
|
|
|
|
|
|
|
} |
77
|
|
|
|
|
|
|
} |
78
|
|
|
|
|
|
|
else { |
79
|
0
|
|
|
|
|
|
$args{triggers} = $default_triggers_ref; |
80
|
|
|
|
|
|
|
} |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
# assign default help triggers for anything not specified by user |
83
|
0
|
|
|
|
|
|
my $default_help_ref = _make_default_help_triggers(); |
84
|
0
|
0
|
|
|
|
|
if ( exists $args{help} ) { |
85
|
0
|
|
|
|
|
|
foreach my $category (qw(mod dist auth)) { |
86
|
0
|
|
|
|
|
|
my $cat_help = $default_help_ref->{ $category }; |
87
|
|
|
|
|
|
|
|
88
|
0
|
0
|
|
|
|
|
$args{help}{ $category } = { |
89
|
|
|
|
|
|
|
%$cat_help, |
90
|
0
|
|
|
|
|
|
%{ $args{help}{ $category } || {} }, |
91
|
|
|
|
|
|
|
}; |
92
|
|
|
|
|
|
|
|
93
|
0
|
|
|
|
|
|
my $cat_trigger = "${category}_cat"; |
94
|
0
|
0
|
|
|
|
|
unless ( exists $args{help}{ $cat_trigger } ) { |
95
|
0
|
|
|
|
|
|
$args{help}{ $cat_trigger } |
96
|
|
|
|
|
|
|
= $default_help_ref->{help}{ $cat_trigger }; |
97
|
|
|
|
|
|
|
} |
98
|
|
|
|
|
|
|
} |
99
|
|
|
|
|
|
|
} |
100
|
|
|
|
|
|
|
else { |
101
|
0
|
|
|
|
|
|
$args{help} = $default_help_ref; |
102
|
|
|
|
|
|
|
} |
103
|
|
|
|
|
|
|
|
104
|
0
|
0
|
|
|
|
|
unless ( exists $args{help}{help_re} ) { |
105
|
0
|
|
|
|
|
|
$args{help}{help_re} = $default_help_ref->{help_re}; |
106
|
|
|
|
|
|
|
} |
107
|
|
|
|
|
|
|
|
108
|
0
|
|
|
|
|
|
return bless \%args, $package; |
109
|
|
|
|
|
|
|
} |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
sub PCI_register { |
112
|
0
|
|
|
0
|
0
|
|
my ( $self, $irc ) = splice @_, 0, 2; |
113
|
|
|
|
|
|
|
|
114
|
0
|
|
|
|
|
|
$self->{irc} = $irc; |
115
|
|
|
|
|
|
|
|
116
|
0
|
|
|
|
|
|
$irc->plugin_register( $self, 'SERVER', qw(notice public msg) ); |
117
|
|
|
|
|
|
|
|
118
|
0
|
|
|
|
|
|
$self->{_session_id} = POE::Session->create( |
119
|
|
|
|
|
|
|
object_states => [ |
120
|
|
|
|
|
|
|
$self => [ |
121
|
|
|
|
|
|
|
qw( |
122
|
|
|
|
|
|
|
_start |
123
|
|
|
|
|
|
|
_shutdown |
124
|
|
|
|
|
|
|
_fetched |
125
|
|
|
|
|
|
|
_freshen |
126
|
|
|
|
|
|
|
_got_info |
127
|
|
|
|
|
|
|
) |
128
|
|
|
|
|
|
|
] |
129
|
|
|
|
|
|
|
], |
130
|
|
|
|
|
|
|
)->ID; |
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
|
133
|
0
|
|
|
|
|
|
return 1; |
134
|
|
|
|
|
|
|
} |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
sub _start { |
137
|
0
|
|
|
0
|
|
|
my ( $kernel, $self ) = @_[ KERNEL, OBJECT ]; |
138
|
0
|
|
|
|
|
|
$self->{_session_id} = $_[SESSION]->ID(); |
139
|
0
|
|
|
|
|
|
$kernel->refcount_increment( $self->{_session_id}, __PACKAGE__ ); |
140
|
|
|
|
|
|
|
|
141
|
0
|
|
|
|
|
|
$self->{poco} = POE::Component::CPAN::SQLite::Info->spawn( |
142
|
0
|
|
|
|
|
|
map { $_, $self->{$_} } |
143
|
|
|
|
|
|
|
qw(mirror debug path) |
144
|
|
|
|
|
|
|
); |
145
|
|
|
|
|
|
|
|
146
|
0
|
0
|
|
|
|
|
warn "Sending `freshen` request to PoCo::CPAN::SQLite::Info" |
147
|
|
|
|
|
|
|
if $self->{debug}; |
148
|
|
|
|
|
|
|
|
149
|
0
|
|
|
|
|
|
$self->{poco}->freshen( { |
150
|
|
|
|
|
|
|
event => '_fetched', |
151
|
|
|
|
|
|
|
ua_args => $self->{ua_args}, |
152
|
|
|
|
|
|
|
} |
153
|
|
|
|
|
|
|
); |
154
|
0
|
|
|
|
|
|
$self->{_freshen_alarm} = $kernel->delay( |
155
|
|
|
|
|
|
|
'_freshen' => $self->{freshen_interval} |
156
|
|
|
|
|
|
|
); |
157
|
0
|
|
|
|
|
|
undef; |
158
|
|
|
|
|
|
|
} |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
sub _shutdown { |
161
|
0
|
|
|
0
|
|
|
my ($kernel, $self) = @_[ KERNEL, OBJECT ]; |
162
|
0
|
|
|
|
|
|
$self->{poco}->shutdown; |
163
|
0
|
|
|
|
|
|
$kernel->alarm_remove_all(); |
164
|
0
|
|
|
|
|
|
$kernel->refcount_decrement( $self->{_session_id}, __PACKAGE__ ); |
165
|
0
|
|
|
|
|
|
undef; |
166
|
|
|
|
|
|
|
} |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
sub PCI_unregister { |
169
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
# Plugin is dying make sure our POE session does as well. |
172
|
0
|
|
|
|
|
|
$poe_kernel->call( $self->{_session_id} => '_shutdown' ); |
173
|
|
|
|
|
|
|
|
174
|
0
|
|
|
|
|
|
delete $self->{irc}; |
175
|
|
|
|
|
|
|
|
176
|
0
|
|
|
|
|
|
return 1; |
177
|
|
|
|
|
|
|
} |
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
sub _freshen { |
181
|
0
|
|
|
0
|
|
|
my ( $kernel, $self ) = @_[ KERNEL, OBJECT ]; |
182
|
|
|
|
|
|
|
|
183
|
0
|
|
|
|
|
|
$self->{poco}->freshen( { |
184
|
|
|
|
|
|
|
event => '_fetched', |
185
|
|
|
|
|
|
|
ua_args => $self->{ua_args}, |
186
|
|
|
|
|
|
|
} |
187
|
|
|
|
|
|
|
); |
188
|
|
|
|
|
|
|
|
189
|
0
|
|
|
|
|
|
$self->{_freshen_alarm} = $kernel->delay( |
190
|
|
|
|
|
|
|
'_freshen' => $self->{freshen_delay} |
191
|
|
|
|
|
|
|
); |
192
|
|
|
|
|
|
|
} |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
sub _fetched { |
195
|
0
|
|
|
0
|
|
|
my ( $kernel, $self, $input ) = @_[ KERNEL, OBJECT, ARG0 ]; |
196
|
|
|
|
|
|
|
|
197
|
0
|
0
|
|
|
|
|
if ( $input->{freshen_error} ) { |
198
|
0
|
0
|
|
|
|
|
if ( $self->{debug} ) { |
199
|
0
|
0
|
|
|
|
|
if ( $input->{freshen_error} eq 'fetch' ) { |
200
|
0
|
|
|
|
|
|
warn "Could not fetch file(s)\n"; |
201
|
0
|
|
|
|
|
|
foreach my $file ( keys %{ $input->{freshen_errors} } ) { |
|
0
|
|
|
|
|
|
|
202
|
0
|
|
|
|
|
|
print "\t$file => $input->{freshen_errors}{ $file }\n"; |
203
|
|
|
|
|
|
|
} |
204
|
|
|
|
|
|
|
} |
205
|
|
|
|
|
|
|
else { |
206
|
0
|
|
|
|
|
|
warn "Failed to create storage dir:" |
207
|
|
|
|
|
|
|
. " $input->{freshen_error}\n"; |
208
|
|
|
|
|
|
|
} |
209
|
|
|
|
|
|
|
} |
210
|
0
|
0
|
|
|
|
|
$self->{_freshen_alarm} = $kernel->delay( |
211
|
|
|
|
|
|
|
'_freshen' => $self->{freshen_interval} < 30 |
212
|
|
|
|
|
|
|
? $self->{freshen_interval} : 30, |
213
|
|
|
|
|
|
|
); |
214
|
|
|
|
|
|
|
} |
215
|
|
|
|
|
|
|
else { |
216
|
0
|
0
|
|
|
|
|
warn "`freshen` success sending `fetch_info` request" |
217
|
|
|
|
|
|
|
if $self->{debug}; |
218
|
|
|
|
|
|
|
|
219
|
0
|
|
|
|
|
|
$self->{poco}->fetch_info( { event => '_got_info' } ); |
220
|
|
|
|
|
|
|
} |
221
|
|
|
|
|
|
|
} |
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
sub _got_info { |
224
|
0
|
|
|
0
|
|
|
my ( $self, $input ) = @_[ OBJECT, ARG0 ]; |
225
|
|
|
|
|
|
|
|
226
|
0
|
0
|
|
|
|
|
warn "_got_info success" |
227
|
|
|
|
|
|
|
if $self->{debug}; |
228
|
|
|
|
|
|
|
|
229
|
0
|
|
|
|
|
|
delete $input->{path}; |
230
|
|
|
|
|
|
|
|
231
|
0
|
|
|
|
|
|
$self->{_data} = $input; |
232
|
|
|
|
|
|
|
|
233
|
0
|
0
|
|
|
|
|
$self->{irc}->send_event( $self->{got_info_event} => time() ) |
234
|
|
|
|
|
|
|
if $self->{send_events}; |
235
|
|
|
|
|
|
|
} |
236
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
sub S_public { |
238
|
0
|
|
|
0
|
0
|
|
my ( $self, $irc ) = splice @_, 0, 2; |
239
|
0
|
|
|
|
|
|
my $who = ${ $_[0] }; |
|
0
|
|
|
|
|
|
|
240
|
0
|
|
|
|
|
|
my $channel = ${ $_[1] }->[0]; |
|
0
|
|
|
|
|
|
|
241
|
0
|
|
|
|
|
|
my $message = ${ $_[2] }; |
|
0
|
|
|
|
|
|
|
242
|
0
|
|
|
|
|
|
return $self->_parse_input( $irc, $who, $channel, $message, 'public' ); |
243
|
|
|
|
|
|
|
} |
244
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
sub S_notice { |
246
|
0
|
|
|
0
|
0
|
|
my ( $self, $irc ) = splice @_, 0, 2; |
247
|
0
|
|
|
|
|
|
my $who = ${ $_[0] }; |
|
0
|
|
|
|
|
|
|
248
|
0
|
|
|
|
|
|
my $channel = ${ $_[1] }->[0]; |
|
0
|
|
|
|
|
|
|
249
|
0
|
|
|
|
|
|
my $message = ${ $_[2] }; |
|
0
|
|
|
|
|
|
|
250
|
0
|
|
|
|
|
|
return $self->_parse_input( $irc, $who, $channel, $message, 'notice' ); |
251
|
|
|
|
|
|
|
} |
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
sub S_msg { |
254
|
0
|
|
|
0
|
0
|
|
my ( $self, $irc ) = splice @_, 0, 2; |
255
|
0
|
|
|
|
|
|
my $who = ${ $_[0] }; |
|
0
|
|
|
|
|
|
|
256
|
0
|
|
|
|
|
|
my $channel = ${ $_[1] }->[0]; |
|
0
|
|
|
|
|
|
|
257
|
0
|
|
|
|
|
|
my $message = ${ $_[2] }; |
|
0
|
|
|
|
|
|
|
258
|
0
|
|
|
|
|
|
return $self->_parse_input( $irc, $who, $channel, $message, 'privmsg' ); |
259
|
|
|
|
|
|
|
} |
260
|
|
|
|
|
|
|
|
261
|
|
|
|
|
|
|
sub _parse_input { |
262
|
0
|
|
|
0
|
|
|
my ( $self, $irc, $who, $channel, $message, $type ) = @_; |
263
|
|
|
|
|
|
|
|
264
|
0
|
0
|
0
|
|
|
|
return PCI_EAT_NONE |
265
|
|
|
|
|
|
|
if !exists $self->{listen_for_input}{ $type } |
266
|
|
|
|
|
|
|
and !$self->{send_events}; |
267
|
|
|
|
|
|
|
|
268
|
0
|
0
|
|
|
|
|
foreach my $ban_re ( @{ $self->{banned} || [] } ) { |
|
0
|
|
|
|
|
|
|
269
|
0
|
0
|
|
|
|
|
return PCI_EAT_NONE |
270
|
|
|
|
|
|
|
if $who =~ /$ban_re/; |
271
|
|
|
|
|
|
|
} |
272
|
|
|
|
|
|
|
|
273
|
0
|
|
|
|
|
|
my $my_nick = $irc->nick_name(); |
274
|
0
|
|
|
|
|
|
my $what; |
275
|
0
|
0
|
|
|
|
|
if ( $type eq 'public' ) { |
276
|
0
|
|
|
|
|
|
($what) = $message =~ m/^\s*\Q$my_nick\E[\:\,\;\.]?\s*(.*)$/i; |
277
|
|
|
|
|
|
|
} |
278
|
|
|
|
|
|
|
else { |
279
|
0
|
|
|
|
|
|
$what = $message; |
280
|
|
|
|
|
|
|
} |
281
|
|
|
|
|
|
|
|
282
|
0
|
0
|
|
|
|
|
return PCI_EAT_NONE |
283
|
|
|
|
|
|
|
unless defined $what; |
284
|
|
|
|
|
|
|
|
285
|
0
|
0
|
|
|
|
|
warn "Got PUBLIC input: [ who => $who, channel => $channel, " |
286
|
|
|
|
|
|
|
. "what => $what ]" |
287
|
|
|
|
|
|
|
if $self->{debug}; |
288
|
|
|
|
|
|
|
|
289
|
0
|
|
|
|
|
|
my $response; |
290
|
|
|
|
|
|
|
|
291
|
0
|
|
|
|
|
|
eval { $response = $self->_parse_commands( $what ); }; |
|
0
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
# if $@ => did not match trigger, |
293
|
|
|
|
|
|
|
# if undef $response => no data available for this request |
294
|
0
|
0
|
|
|
|
|
if ( $@ ) { |
295
|
0
|
0
|
0
|
|
|
|
$response = $self->_parse_help( $what ) |
296
|
|
|
|
|
|
|
if $self->{help} |
297
|
|
|
|
|
|
|
and exists $self->{listen_for_help}{ $type }; |
298
|
|
|
|
|
|
|
|
299
|
0
|
0
|
0
|
|
|
|
warn "_parse_command( $what ) did not match anything" |
300
|
|
|
|
|
|
|
if $self->{debug} and not defined $response; |
301
|
|
|
|
|
|
|
|
302
|
0
|
0
|
|
|
|
|
return PCI_EAT_NONE |
303
|
|
|
|
|
|
|
unless defined $response; |
304
|
|
|
|
|
|
|
} |
305
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
|
307
|
0
|
|
|
|
|
|
my ( $nick ) = split /!/, $who; |
308
|
0
|
0
|
|
|
|
|
unless ( defined $response ) { |
309
|
0
|
0
|
|
|
|
|
if ( $self->{respond_no_result} ) { |
310
|
0
|
|
|
|
|
|
my $responses_ref = $self->{no_result_responses}; |
311
|
|
|
|
|
|
|
|
312
|
0
|
0
|
|
|
|
|
if ( $type eq 'public' ) { |
313
|
0
|
|
|
|
|
|
$poe_kernel->post( $irc => privmsg => $channel => |
314
|
|
|
|
|
|
|
"$nick, " . $responses_ref->[ rand @$responses_ref ] |
315
|
|
|
|
|
|
|
); |
316
|
|
|
|
|
|
|
} |
317
|
|
|
|
|
|
|
else { |
318
|
0
|
|
|
|
|
|
$poe_kernel->post( $irc => $type => $nick => |
319
|
|
|
|
|
|
|
$responses_ref->[ rand @$responses_ref ] |
320
|
|
|
|
|
|
|
); |
321
|
|
|
|
|
|
|
} |
322
|
|
|
|
|
|
|
} |
323
|
0
|
0
|
|
|
|
|
$self->{irc}->send_event( |
324
|
|
|
|
|
|
|
$self->{no_result_event} => { |
325
|
|
|
|
|
|
|
'time' => time(), |
326
|
|
|
|
|
|
|
who => $who, |
327
|
|
|
|
|
|
|
channel => $channel, |
328
|
|
|
|
|
|
|
what => $message, |
329
|
|
|
|
|
|
|
type => $type, |
330
|
|
|
|
|
|
|
} |
331
|
|
|
|
|
|
|
) if $self->{send_events}; |
332
|
|
|
|
|
|
|
|
333
|
0
|
|
|
|
|
|
return PCI_EAT_NONE; |
334
|
|
|
|
|
|
|
} |
335
|
|
|
|
|
|
|
|
336
|
0
|
0
|
|
|
|
|
warn "Got response `$response`" |
337
|
|
|
|
|
|
|
if $self->{debug}; |
338
|
|
|
|
|
|
|
|
339
|
|
|
|
|
|
|
my $max_length = $type eq 'public' |
340
|
|
|
|
|
|
|
? $self->{max_output_length_pub} |
341
|
0
|
0
|
|
|
|
|
: $self->{max_output_length }; |
342
|
|
|
|
|
|
|
|
343
|
0
|
0
|
|
|
|
|
if ( length $response > $max_length ) { |
344
|
0
|
|
|
|
|
|
$response = substr $response, 0, $max_length - 3; |
345
|
0
|
|
|
|
|
|
$response .= '...'; |
346
|
|
|
|
|
|
|
} |
347
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
# break long output into several lines to prefed "Excess Flood" drops |
349
|
0
|
|
|
|
|
|
my @responses; |
350
|
0
|
|
|
|
|
|
while ( length $response > $self->{output_line_length} ) { |
351
|
0
|
|
|
|
|
|
push @responses, substr $response, 0, $self->{output_line_length}; |
352
|
0
|
|
|
|
|
|
$response = substr $response, $self->{output_line_length}; |
353
|
|
|
|
|
|
|
} |
354
|
0
|
|
|
|
|
|
push @responses, $response; |
355
|
|
|
|
|
|
|
|
356
|
0
|
0
|
|
|
|
|
if ( exists $self->{ listen_for_input }{ $type } ) { |
357
|
0
|
0
|
|
|
|
|
if ( $type eq 'public' ) { |
358
|
|
|
|
|
|
|
$poe_kernel->post( $irc => privmsg => $channel => |
359
|
|
|
|
|
|
|
"$nick, $_" |
360
|
0
|
|
|
|
|
|
) for @responses; |
361
|
|
|
|
|
|
|
} |
362
|
|
|
|
|
|
|
else { |
363
|
|
|
|
|
|
|
$poe_kernel->post( $irc => $type => $nick => $_ ) |
364
|
0
|
|
|
|
|
|
for @responses; |
365
|
|
|
|
|
|
|
} |
366
|
|
|
|
|
|
|
} |
367
|
|
|
|
|
|
|
|
368
|
0
|
0
|
|
|
|
|
if ( $self->{send_events} ) { |
369
|
0
|
|
|
|
|
|
for ( @responses ) { |
370
|
0
|
|
|
|
|
|
$self->{irc}->send_event( |
371
|
|
|
|
|
|
|
$self->{response_event} => { |
372
|
|
|
|
|
|
|
'time' => time(), |
373
|
|
|
|
|
|
|
who => $who, |
374
|
|
|
|
|
|
|
channel => $channel, |
375
|
|
|
|
|
|
|
what => $message, |
376
|
|
|
|
|
|
|
type => $type, |
377
|
|
|
|
|
|
|
response => $_ |
378
|
|
|
|
|
|
|
} |
379
|
|
|
|
|
|
|
); |
380
|
|
|
|
|
|
|
} |
381
|
|
|
|
|
|
|
} |
382
|
|
|
|
|
|
|
|
383
|
0
|
0
|
|
|
|
|
return $self->{eat} ? PCI_EAT_ALL : PCI_EAT_NONE; |
384
|
|
|
|
|
|
|
} |
385
|
|
|
|
|
|
|
|
386
|
|
|
|
|
|
|
sub _parse_help { |
387
|
0
|
|
|
0
|
|
|
my ( $self, $what ) = @_; |
388
|
0
|
|
|
|
|
|
my $trigs = _make_default_help_triggers(); |
389
|
|
|
|
|
|
|
|
390
|
|
|
|
|
|
|
return |
391
|
0
|
0
|
0
|
|
|
|
unless defined $what and $what =~ s/$trigs->{help_re}//; |
392
|
|
|
|
|
|
|
|
393
|
0
|
0
|
|
|
|
|
return $self->_make_help_list |
394
|
|
|
|
|
|
|
unless length $what; |
395
|
|
|
|
|
|
|
|
396
|
|
|
|
|
|
|
|
397
|
0
|
|
|
|
|
|
my $help_data_ref = _make_help_data(); |
398
|
0
|
|
|
|
|
|
$what =~ s/^\s+|\s+$//g; |
399
|
0
|
|
|
|
|
|
$what = lc $what; |
400
|
0
|
0
|
|
|
|
|
if ( $what =~ s/^$trigs->{mod_cat}//i ) { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
401
|
0
|
|
|
|
|
|
return $help_data_ref->{mod}{ $what }; |
402
|
|
|
|
|
|
|
} |
403
|
|
|
|
|
|
|
elsif ( $what =~ s/^$trigs->{auth_cat}//i ) { |
404
|
0
|
|
|
|
|
|
return $help_data_ref->{auth}{ $what }; |
405
|
|
|
|
|
|
|
|
406
|
|
|
|
|
|
|
} |
407
|
|
|
|
|
|
|
elsif ( $what =~ s/^$trigs->{dist_cat}//i ) { |
408
|
0
|
|
|
|
|
|
return $help_data_ref->{dist}{ $what }; |
409
|
|
|
|
|
|
|
} |
410
|
0
|
|
|
|
|
|
return; |
411
|
|
|
|
|
|
|
} |
412
|
|
|
|
|
|
|
|
413
|
|
|
|
|
|
|
sub _parse_commands { |
414
|
0
|
|
|
0
|
|
|
my ( $self, $what ) = @_; |
415
|
|
|
|
|
|
|
|
416
|
0
|
|
|
|
|
|
my $response; |
417
|
0
|
0
|
|
|
|
|
if ( $what =~ s/$self->{triggers}{mod_cat}// ) { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
418
|
0
|
|
|
|
|
|
my $triggers = $self->{triggers}{mod}; |
419
|
|
|
|
|
|
|
|
420
|
0
|
0
|
|
|
|
|
if ( $what =~ s/$triggers->{distname}// ) { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
421
|
0
|
|
|
|
|
|
$response = $self->_make_info( mods => $what => 'dist_name' ); |
422
|
|
|
|
|
|
|
} |
423
|
|
|
|
|
|
|
elsif ( $what =~ s/$triggers->{version}// ) { |
424
|
0
|
|
|
|
|
|
$response = $self->_make_info( mods => $what => 'mod_vers' ); |
425
|
|
|
|
|
|
|
} |
426
|
|
|
|
|
|
|
elsif ( $what =~ s/$triggers->{desc}// ) { |
427
|
0
|
|
|
|
|
|
$response = $self->_make_info( mods => $what => 'mod_abs' ); |
428
|
|
|
|
|
|
|
} |
429
|
|
|
|
|
|
|
elsif ( $what =~ s/$triggers->{chapter}// ) { |
430
|
0
|
|
|
|
|
|
$response = $self->_make_info( mods => $what => 'chapterid' ); |
431
|
|
|
|
|
|
|
} |
432
|
|
|
|
|
|
|
elsif ( $what =~ s/$triggers->{dslip}// ) { |
433
|
0
|
|
|
|
|
|
$response = $self->_make_info( mods => $what => 'dslip' ); |
434
|
|
|
|
|
|
|
} |
435
|
|
|
|
|
|
|
else { |
436
|
0
|
|
|
|
|
|
die; |
437
|
|
|
|
|
|
|
} |
438
|
|
|
|
|
|
|
} |
439
|
|
|
|
|
|
|
elsif ( $what =~ s/$self->{triggers}{auth_cat}// ) { |
440
|
0
|
|
|
|
|
|
my $triggers = $self->{triggers}{auth}; |
441
|
|
|
|
|
|
|
|
442
|
0
|
0
|
|
|
|
|
if ( $what =~ s/$triggers->{email}// ) { |
|
|
0
|
|
|
|
|
|
443
|
0
|
|
|
|
|
|
$response = $self->_make_info(auths => uc $what => 'email' ); |
444
|
|
|
|
|
|
|
} |
445
|
|
|
|
|
|
|
elsif ( $what =~ s/$triggers->{name}// ) { |
446
|
0
|
|
|
|
|
|
$response |
447
|
|
|
|
|
|
|
= $self->_make_info( auths => uc $what => 'fullname' ); |
448
|
|
|
|
|
|
|
} |
449
|
|
|
|
|
|
|
else { |
450
|
0
|
|
|
|
|
|
die |
451
|
|
|
|
|
|
|
} |
452
|
|
|
|
|
|
|
} |
453
|
|
|
|
|
|
|
elsif ( $what =~ s/$self->{triggers}{dist_cat}// ) { |
454
|
0
|
|
|
|
|
|
my $triggers = $self->{triggers}{dist}; |
455
|
0
|
0
|
|
|
|
|
if ( $what =~ s/$triggers->{version}// ) { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
456
|
0
|
|
|
|
|
|
$response = $self->_make_info( dists => $what => 'dist_vers'); |
457
|
|
|
|
|
|
|
} |
458
|
|
|
|
|
|
|
elsif ( $what =~ s/$triggers->{file}// ) { |
459
|
0
|
|
|
|
|
|
$response = $self->_make_info( dists => $what => 'dist_file'); |
460
|
|
|
|
|
|
|
} |
461
|
|
|
|
|
|
|
elsif ( $what =~ s/$triggers->{auth}// ) { |
462
|
0
|
|
|
|
|
|
$response = $self->_make_info( dists => $what => 'cpanid' ); |
463
|
|
|
|
|
|
|
} |
464
|
|
|
|
|
|
|
elsif ( $what =~ s/$triggers->{desc}// ) { |
465
|
0
|
|
|
|
|
|
$response = $self->_make_info( dists => $what => 'dist_abs' ); |
466
|
|
|
|
|
|
|
} |
467
|
|
|
|
|
|
|
elsif ( $what =~ s/$triggers->{mods}// ) { |
468
|
0
|
|
|
|
|
|
$response = $self->_make_info( dists => $what => 'modules' ); |
469
|
|
|
|
|
|
|
} |
470
|
|
|
|
|
|
|
elsif ( $what =~ s/$triggers->{chapter}// ) { |
471
|
0
|
|
|
|
|
|
$response = $self->_make_info( dists => $what => 'chapterid' ); |
472
|
|
|
|
|
|
|
} |
473
|
|
|
|
|
|
|
else { |
474
|
0
|
|
|
|
|
|
die; |
475
|
|
|
|
|
|
|
} |
476
|
|
|
|
|
|
|
} |
477
|
|
|
|
|
|
|
else { |
478
|
0
|
|
|
|
|
|
die; |
479
|
|
|
|
|
|
|
} |
480
|
0
|
|
|
|
|
|
return $response; |
481
|
|
|
|
|
|
|
} |
482
|
|
|
|
|
|
|
|
483
|
|
|
|
|
|
|
sub _make_help_list { |
484
|
0
|
|
|
0
|
|
|
my $self = shift; |
485
|
|
|
|
|
|
|
|
486
|
0
|
|
|
|
|
|
my $help_data_ref = _make_default_help_triggers(); |
487
|
0
|
|
|
|
|
|
my @help_list; |
488
|
0
|
|
|
|
|
|
foreach my $category (qw( dist mod auth )) { |
489
|
0
|
|
|
|
|
|
my $cat_prefix = $help_data_ref->{ $category . '_cat' }; |
490
|
0
|
|
|
|
|
|
push @help_list, join q|, |, |
491
|
0
|
|
|
|
|
|
map { $cat_prefix . $_ } |
492
|
0
|
|
|
|
|
|
sort keys %{ $help_data_ref->{ $category } }; |
493
|
|
|
|
|
|
|
} |
494
|
0
|
|
|
|
|
|
return join q|, |, @help_list; |
495
|
|
|
|
|
|
|
} |
496
|
|
|
|
|
|
|
|
497
|
|
|
|
|
|
|
sub _make_info { |
498
|
0
|
|
|
0
|
|
|
my ( $self, $category, $item, $section ) = @_; |
499
|
|
|
|
|
|
|
return |
500
|
0
|
0
|
|
|
|
|
unless defined $section; |
501
|
|
|
|
|
|
|
|
502
|
0
|
|
|
|
|
|
$item =~ s/^\s+|\s+$//g; |
503
|
|
|
|
|
|
|
return |
504
|
0
|
0
|
|
|
|
|
unless length $item; |
505
|
|
|
|
|
|
|
|
506
|
0
|
0
|
|
|
|
|
unless ( exists $self->{_data}{ $category }{ $item } ) { |
507
|
0
|
0
|
|
|
|
|
warn "Did not find {_data}{ $category }{ $item }" |
508
|
|
|
|
|
|
|
if $self->{debug}; |
509
|
|
|
|
|
|
|
|
510
|
0
|
|
|
|
|
|
return; |
511
|
|
|
|
|
|
|
} |
512
|
|
|
|
|
|
|
|
513
|
0
|
|
|
|
|
|
my $data = $self->{_data}{ $category }{ $item }; |
514
|
|
|
|
|
|
|
|
515
|
|
|
|
|
|
|
|
516
|
0
|
0
|
|
|
|
|
if ( exists $data->{ $section } ) { |
517
|
0
|
0
|
|
|
|
|
if ( $category eq 'dists' ) { |
518
|
0
|
0
|
|
|
|
|
if ( $section eq 'modules' ) { |
|
|
0
|
|
|
|
|
|
519
|
0
|
|
|
|
|
|
return $self->_prepare_dist_modules( $data->{ $section } ); |
520
|
|
|
|
|
|
|
} |
521
|
|
|
|
|
|
|
elsif ( $section eq 'chapterid' ) { |
522
|
0
|
|
|
|
|
|
return $self->_prepare_dist_chapterid($data->{ $section }); |
523
|
|
|
|
|
|
|
} |
524
|
|
|
|
|
|
|
} |
525
|
0
|
|
|
|
|
|
return $data->{ $section }; |
526
|
|
|
|
|
|
|
} |
527
|
|
|
|
|
|
|
else { |
528
|
0
|
|
|
|
|
|
return; |
529
|
|
|
|
|
|
|
} |
530
|
|
|
|
|
|
|
} |
531
|
|
|
|
|
|
|
|
532
|
|
|
|
|
|
|
sub _prepare_dist_modules { |
533
|
0
|
|
|
0
|
|
|
my ( $self, $modules_ref ) = @_; |
534
|
|
|
|
|
|
|
return |
535
|
0
|
0
|
|
|
|
|
unless ref $modules_ref eq 'HASH'; |
536
|
|
|
|
|
|
|
|
537
|
0
|
|
|
|
|
|
my @modules = keys %$modules_ref; |
538
|
|
|
|
|
|
|
|
539
|
0
|
0
|
|
|
|
|
if ( @modules > $self->{max_modules_limit} ) { |
540
|
0
|
|
|
|
|
|
return "Uses " . @modules . " modules..."; |
541
|
|
|
|
|
|
|
} |
542
|
|
|
|
|
|
|
else { |
543
|
0
|
|
|
|
|
|
my $mods = join ' | ', @modules; |
544
|
0
|
0
|
|
|
|
|
if ( length $mods > $self->{max_modules_length} ) { |
545
|
0
|
|
|
|
|
|
$mods = "(total: " . @modules . " ) $mods"; |
546
|
0
|
|
|
|
|
|
$mods = substr $mods, 0, $self->{max_modules_length} - 3; |
547
|
0
|
|
|
|
|
|
$mods .= '...'; |
548
|
|
|
|
|
|
|
} |
549
|
0
|
|
|
|
|
|
return $mods; |
550
|
|
|
|
|
|
|
} |
551
|
|
|
|
|
|
|
} |
552
|
|
|
|
|
|
|
|
553
|
|
|
|
|
|
|
sub _make_default_help_triggers { |
554
|
|
|
|
|
|
|
return { |
555
|
0
|
|
|
0
|
|
|
help_re => qr/^help\s*/i, |
556
|
|
|
|
|
|
|
mod_cat => 'mod_', |
557
|
|
|
|
|
|
|
mod => { |
558
|
|
|
|
|
|
|
distname => 'distname', |
559
|
|
|
|
|
|
|
version => 'version', |
560
|
|
|
|
|
|
|
desc => 'desc', |
561
|
|
|
|
|
|
|
chapter => 'chapter', |
562
|
|
|
|
|
|
|
dslip => 'dslip', |
563
|
|
|
|
|
|
|
}, |
564
|
|
|
|
|
|
|
auth_cat => 'auth_', |
565
|
|
|
|
|
|
|
auth => { |
566
|
|
|
|
|
|
|
email => 'email', |
567
|
|
|
|
|
|
|
name => 'name', |
568
|
|
|
|
|
|
|
}, |
569
|
|
|
|
|
|
|
|
570
|
|
|
|
|
|
|
dist_cat => 'dist_', |
571
|
|
|
|
|
|
|
dist => { |
572
|
|
|
|
|
|
|
version => 'version', |
573
|
|
|
|
|
|
|
file => 'file', |
574
|
|
|
|
|
|
|
auth => 'auth', |
575
|
|
|
|
|
|
|
desc => 'desc', |
576
|
|
|
|
|
|
|
mods => 'mods', |
577
|
|
|
|
|
|
|
chapter => 'chapter', |
578
|
|
|
|
|
|
|
}, |
579
|
|
|
|
|
|
|
}; |
580
|
|
|
|
|
|
|
} |
581
|
|
|
|
|
|
|
|
582
|
|
|
|
|
|
|
sub _make_help_data { |
583
|
|
|
|
|
|
|
return { |
584
|
0
|
|
|
0
|
|
|
mod => { |
585
|
|
|
|
|
|
|
distname => q|Which distribution the module is in|, |
586
|
|
|
|
|
|
|
version => q|Module's version|, |
587
|
|
|
|
|
|
|
desc => q|Module's description|, |
588
|
|
|
|
|
|
|
chapter => q|Module's chapter|, |
589
|
|
|
|
|
|
|
dslip => q|Module's DSLIP code|, |
590
|
|
|
|
|
|
|
}, |
591
|
|
|
|
|
|
|
auth => { |
592
|
|
|
|
|
|
|
email => q|Author's e-mail address|, |
593
|
|
|
|
|
|
|
name => q|Author's full name|, |
594
|
|
|
|
|
|
|
}, |
595
|
|
|
|
|
|
|
dist => { |
596
|
|
|
|
|
|
|
version => q|Distribution's version|, |
597
|
|
|
|
|
|
|
file => q|Distribution's CPAN filename|, |
598
|
|
|
|
|
|
|
auth => q|Distribution's author|, |
599
|
|
|
|
|
|
|
desc => q|Distribution's description|, |
600
|
|
|
|
|
|
|
mods => q|List modules included in the distribution|, |
601
|
|
|
|
|
|
|
chapter => q|Chapter and subchapter of the distribution|, |
602
|
|
|
|
|
|
|
}, |
603
|
|
|
|
|
|
|
}; |
604
|
|
|
|
|
|
|
} |
605
|
|
|
|
|
|
|
|
606
|
|
|
|
|
|
|
sub _make_default_triggers { |
607
|
|
|
|
|
|
|
return { |
608
|
0
|
|
|
0
|
|
|
mod_cat => qr/ ^ mod_ /xi, |
609
|
|
|
|
|
|
|
mod => { |
610
|
|
|
|
|
|
|
distname => qr/ ^ distname \s+ /xi, |
611
|
|
|
|
|
|
|
version => qr/ ^ version \s+ /xi, |
612
|
|
|
|
|
|
|
desc => qr/ ^ desc \s+ /xi, |
613
|
|
|
|
|
|
|
chapter => qr/ ^ chapter \s+ /xi, |
614
|
|
|
|
|
|
|
dslip => qr/ ^ dslip \s+ /xi, |
615
|
|
|
|
|
|
|
}, |
616
|
|
|
|
|
|
|
|
617
|
|
|
|
|
|
|
auth_cat => qr/ ^auth_ /xi, |
618
|
|
|
|
|
|
|
auth => { |
619
|
|
|
|
|
|
|
email => qr/ ^ email \s+ /xi, |
620
|
|
|
|
|
|
|
name => qr/ ^ name \s+ /xi, |
621
|
|
|
|
|
|
|
}, |
622
|
|
|
|
|
|
|
|
623
|
|
|
|
|
|
|
dist_cat => qr/ ^ dist_ /xi, |
624
|
|
|
|
|
|
|
dist => { |
625
|
|
|
|
|
|
|
version => qr/ ^ version \s+ /xi, |
626
|
|
|
|
|
|
|
file => qr/ ^ file \s+ /xi, |
627
|
|
|
|
|
|
|
auth => qr/ ^ auth \s+ /xi, |
628
|
|
|
|
|
|
|
desc => qr/ ^ desc \s+ /xi, |
629
|
|
|
|
|
|
|
mods => qr/ ^ mods \s+ /xi, |
630
|
|
|
|
|
|
|
chapter => qr/ ^ chapter \s+ /xi, |
631
|
|
|
|
|
|
|
}, |
632
|
|
|
|
|
|
|
}; |
633
|
|
|
|
|
|
|
} |
634
|
|
|
|
|
|
|
|
635
|
|
|
|
|
|
|
1; |
636
|
|
|
|
|
|
|
__END__ |