File Coverage

blib/lib/App/Pocosi/ReadLine.pm
Criterion Covered Total %
statement 32 89 35.9
branch 0 20 0.0
condition 0 6 0.0
subroutine 12 20 60.0
pod 0 6 0.0
total 44 141 31.2


line stmt bran cond sub pod time code
1             package App::Pocosi::ReadLine;
2             BEGIN {
3 1     1   1216 $App::Pocosi::ReadLine::AUTHORITY = 'cpan:HINRIK';
4             }
5             BEGIN {
6 1     1   16 $App::Pocosi::ReadLine::VERSION = '0.03';
7             }
8              
9 1     1   8 use strict;
  1         2  
  1         33  
10 1     1   5 use warnings FATAL => 'all';
  1         22  
  1         54  
11 1     1   5 use Carp;
  1         1  
  1         67  
12 1     1   888 use Data::Dump 'dump';
  1         6649  
  1         82  
13 1     1   804 use IO::WrapOutput;
  1         724  
  1         52  
14 1     1   6 use POE;
  1         1  
  1         11  
15 1     1   314 use POE::Component::Server::IRC::Plugin qw(PCSI_EAT_NONE);
  1         3  
  1         40  
16 1     1   1525 use POE::Wheel::ReadLine;
  1         38711  
  1         46  
17 1     1   1874 use POE::Wheel::ReadWrite;
  1         12565  
  1         42  
18 1     1   12 use Symbol qw(gensym);
  1         2  
  1         1187  
19              
20             sub new {
21 0     0 0   my ($package) = shift;
22 0 0         croak "$package requires an even number of arguments" if @_ & 1;
23 0           my $self = bless { @_ }, $package;
24 0           return $self;
25             }
26              
27             sub PCSI_register {
28 0     0 0   my ($self, $ircd, %args) = @_;
29 0           $self->{ircd} = $ircd;
30              
31 0           POE::Session->create(
32             object_states => [
33             $self => [qw(
34             _start
35             got_user_input
36             got_output
37             restore_stdio
38             )],
39             ],
40             );
41 0           return 1;
42             }
43              
44             sub PCSI_unregister {
45 0     0 0   my ($self, $ircd, %args) = @_;
46 0           $poe_kernel->call($self->{session_id}, 'restore_stdio');
47 0           return 1;
48             }
49              
50             sub _start {
51 0     0     my ($kernel, $session, $self) = @_[KERNEL, SESSION, OBJECT];
52              
53 0           $self->{session_id} = $session->ID();
54 0           $self->{console} = POE::Wheel::ReadLine->new(
55             InputEvent => 'got_user_input',
56             PutMode => 'immediate',
57             AppName => 'pocosi',
58             );
59              
60 0           my ($stdout, $stderr) = wrap_output();
61              
62 0           $self->{stderr_reader} = POE::Wheel::ReadWrite->new(
63             Handle => $stderr,
64             InputEvent => 'got_output',
65             );
66 0           $self->{stdout_reader} = POE::Wheel::ReadWrite->new(
67             Handle => $stdout,
68             InputEvent => 'got_output',
69             );
70              
71 0           $self->{console}->get();
72 0           return;
73             }
74              
75             sub got_output {
76 0     0 0   my ($self, $line) = @_[OBJECT, ARG0];
77 0           $self->{console}->put($line);
78 0           return;
79             }
80              
81             sub got_user_input {
82 0     0 0   my ($self, $line, $ex) = @_[OBJECT, ARG0, ARG1];
83              
84 0 0 0       if (defined $ex && $ex eq 'interrupt') {
85 0           $self->{Pocosi}->shutdown('Exiting due to user interruption');
86 0           return;
87             }
88              
89 0 0 0       if (defined $line && length $line) {
90 0           $self->{console}->add_history($line);
91              
92 0 0         if (my ($feature) = $line =~ /^(verbose|trace)\s*$/) {
    0          
    0          
93 0 0         if ($self->{Pocosi}->$feature()) {
94 0           $self->{Pocosi}->$feature(0);
95 0           print "Disabled '$feature'\n";
96             }
97             else {
98 0           $self->{Pocosi}->$feature(1);
99 0           print "Enabled '$feature'\n";
100             }
101             }
102             elsif (my ($cmd, $args) = $line =~ m{^/([a-z_]+)\s*(.+)?}) {
103 0 0         my @args = defined $args ? eval $args : ();
104 0           $self->{ircd}->yield($cmd, @args);
105             }
106             elsif (my ($method, $params) = $line =~ m{^\.([a-z_]+)\s*(.+)?}) {
107 0 0         my @params = defined $params ? eval $params : ();
108              
109 0           local ($@, $!);
110 0           eval {
111 0           print dump($self->{ircd}->$method(@params)), "\n";
112             };
113 0 0         if (my $err = $@) {
114 0           chomp $err;
115 0           my $our_file = __FILE__;
116 0           $err =~ s{ at \Q$our_file\E line [0-9]+\.$}{};
117 0           warn $err, "\n";
118             }
119             }
120             else {
121 0           $self->_print_help();
122             }
123             }
124              
125 0           $self->{console}->get();
126 0           return;
127             }
128              
129             sub _print_help {
130 0     0     my ($self) = @_;
131              
132 0           print <<'EOF';
133             Type ".foo 'bar', 'baz'" to call the method "foo" with the arguments 'bar'
134             and 'baz' on the IRCd component. You must quote your arguments since they
135             will be eval'd, and don't forget to use commas between arguments.
136              
137             Type "/foo 'bar', 'baz'" to call the POE::Component::Server::IRC command foo
138             with the arguments 'bar' and 'baz'. This is equivalent to: .yield 'foo',
139             'bar', 'baz'
140              
141             Type "verbose" and "trace" to flip those features on/off.
142             EOF
143              
144 0           return;
145             }
146              
147             sub restore_stdio {
148 0     0 0   my ($self) = $_[OBJECT];
149              
150 0           unwrap_output();
151 0           delete $self->{console};
152 0           delete $self->{stderr_reader};
153 0           delete $self->{stdout_reader};
154 0           return;
155             }
156              
157             1;
158              
159             =encoding utf8
160              
161             =head1 NAME
162              
163             App::Pocosi::ReadLine - A PoCo-Server-IRC plugin which provides a ReadLine UI
164              
165             =head1 DESCRIPTION
166              
167             This plugin is used internally by L. No need for
168             you to use it.
169              
170             =head1 AUTHOR
171              
172             Hinrik Ern SigurEsson, hinrik.sig@gmail.com
173              
174             =cut