File Coverage

blib/lib/POE/Component/WWW/XKCD/AsText.pm
Criterion Covered Total %
statement 78 115 67.8
branch 21 44 47.7
condition n/a
subroutine 15 20 75.0
pod 4 4 100.0
total 118 183 64.4


line stmt bran cond sub pod time code
1             package POE::Component::WWW::XKCD::AsText;
2              
3 6     6   1283312 use warnings;
  6         19  
  6         229  
4 6     6   32 use strict;
  6         13  
  6         281  
5              
6             our $VERSION = '0.002';
7              
8 6     6   46 use Carp;
  6         33  
  6         428  
9 6     6   4632 use WWW::XKCD::AsText;
  6         414841  
  6         264  
10 6     6   58 use POE qw( Filter::Reference Filter::Line Wheel::Run );
  6         12  
  6         97  
11              
12             sub spawn {
13 6     6 1 350 my $package = shift;
14 6 50       35 croak "$package requires an even number of arguments"
15             if @_ & 1;
16              
17 6         35 my %params = @_;
18              
19 6         58 $params{ lc $_ } = delete $params{ $_ } for keys %params;
20              
21 6 50       38 delete $params{options}
22             unless ref $params{options} eq 'HASH';
23              
24 6         49 $params{obj_args} = {
25             timeout => delete( $params{timeout} ),
26             ua => delete( $params{ua} ),
27             };
28              
29 6         27 my $self = bless \%params, $package;
30              
31 6 50       145 $self->{session_id} = POE::Session->create(
32             object_states => [
33             $self => {
34             retrieve => '_retrieve',
35             shutdown => '_shutdown',
36             },
37             $self => [
38             qw(
39             _child_error
40             _child_closed
41             _child_stdout
42             _child_stderr
43             _sig_child
44             _start
45             )
46             ]
47             ],
48             ( defined $params{options} ? ( options => $params{options} ) : () ),
49             )->ID();
50              
51 6         2360 return $self;
52             }
53              
54              
55             sub _start {
56 6     6   1913 my ( $kernel, $self ) = @_[ KERNEL, OBJECT ];
57 6         31 $self->{session_id} = $_[SESSION]->ID();
58              
59 6 100       48 if ( $self->{alias} ) {
60 2         12 $kernel->alias_set( $self->{alias} );
61             }
62             else {
63 4         24 $kernel->refcount_increment( $self->{session_id} => __PACKAGE__ );
64             }
65              
66             $self->{wheel} = POE::Wheel::Run->new(
67 0     0   0 Program => sub{ _wheel( $self->{obj_args} ); },
68 6 50       289 ErrorEvent => '_child_error',
69             CloseEvent => '_child_close',
70             StdoutEvent => '_child_stdout',
71             StderrEvent => '_child_stderr',
72             StdioFilter => POE::Filter::Reference->new,
73             StderrFilter => POE::Filter::Line->new,
74             ( $^O eq 'MSWin32' ? ( CloseOnCall => 0 ) : ( CloseOnCall => 1 ) )
75             );
76              
77 6 50       37892 $kernel->yield('shutdown')
78             unless $self->{wheel};
79              
80 6         236 $kernel->sig_child( $self->{wheel}->PID(), '_sig_child' );
81              
82 6         2475 undef;
83             }
84              
85             sub _sig_child {
86 6     6   20941 $poe_kernel->sig_handled;
87             }
88              
89             sub session_id {
90 0     0 1 0 return $_[0]->{session_id};
91             }
92              
93             sub retrieve {
94 3     3 1 1788 my $self = shift;
95 3         75 $poe_kernel->post( $self->{session_id} => 'retrieve' => @_ );
96             }
97              
98             sub _retrieve {
99 5     5   5515 my ( $kernel, $self ) = @_[ KERNEL, OBJECT ];
100 5         79 my $sender = $_[SENDER]->ID;
101              
102             return
103 5 50       60 if $self->{shutdown};
104              
105 5         18 my $args;
106 5 50       68 if ( ref $_[ARG0] eq 'HASH' ) {
107 5         9 $args = { %{ $_[ARG0] } };
  5         33  
108             }
109             else {
110 0         0 carp "First parameter must be a hashref, trying to adjust...";
111 0         0 $args = { @_[ARG0 .. $#_] };
112             }
113 17         385 $args->{ lc $_ } = delete $args->{ $_ }
114 5         55 for grep { !/^_/ } keys %$args;
115              
116 5 50       43 unless ( $args->{event} ) {
117 0         0 carp "Missing 'event' parameter to retrieve";
118 0         0 return;
119             }
120 5 50       57 unless ( $args->{id} ) {
121 0         0 carp "Missing 'id' parameter to retrieve";
122 0         0 return;
123             }
124              
125 5         33 $args->{id} =~ s/\s+//g;
126              
127 5 50       87 if ( $args->{id} =~ /\D/ ) {
128 0         0 carp "ID number must be a NUMBER";
129 0         0 return;
130             }
131              
132 5 100       35 if ( $args->{session} ) {
133 2 50       18 if ( my $ref = $kernel->alias_resolve( $args->{session} ) ) {
134 2         98 $args->{sender} = $ref->ID;
135             }
136             else {
137 0         0 carp "Could not resolve 'session' parameter to a valid"
138             . " POE session";
139 0         0 return;
140             }
141             }
142             else {
143 3         18 $args->{sender} = $sender;
144             }
145              
146 5         49 $kernel->refcount_increment( $args->{sender} => __PACKAGE__ );
147 5         378 $self->{wheel}->put( $args );
148              
149 5         1685 undef;
150             }
151              
152             sub shutdown {
153 4     4 1 12937 my $self = shift;
154 4         56 $poe_kernel->call( $self->{session_id} => 'shutdown' => @_ );
155             }
156              
157             sub _shutdown {
158 6     6   8919 my ( $kernel, $self ) = @_[ KERNEL, OBJECT ];
159 6         57 $kernel->alarm_remove_all;
160 6         514 $kernel->alias_remove( $_ ) for $kernel->alias_list;
161 6 100       387 $kernel->refcount_decrement( $self->{session_id} => __PACKAGE__ )
162             unless $self->{alias};
163              
164 6         245 $self->{shutdown} = 1;
165              
166 6 50       129 $self->{wheel}->shutdown_stdin
167             if $self->{wheel};
168             }
169              
170             sub _child_closed {
171 0     0   0 my ( $kernel, $self ) = @_[ KERNEL, OBJECT ];
172              
173 0 0       0 carp "_child_closed called (@_[ARG0..$#_])\n"
174             if $self->{debug};
175              
176 0         0 delete $self->{wheel};
177 0 0       0 $kernel->yield('shutdown')
178             unless $self->{shutdown};
179              
180 0         0 undef;
181             }
182              
183             sub _child_error {
184 6     6   2802840 my ( $kernel, $self ) = @_[ KERNEL, OBJECT ];
185 6 50       1943 carp "_child_error called (@_[ARG0..$#_])\n"
186             if $self->{debug};
187              
188 6         5477 delete $self->{wheel};
189 6 50       3215 $kernel->yield('shutdown')
190             unless $self->{shutdown};
191              
192 6         35 undef;
193             }
194              
195             sub _child_stderr {
196 1     1   2494784 my ( $kernel, $self ) = @_[ KERNEL, OBJECT ];
197 1 50       428 carp "_child_stderr: $_[ARG0]\n"
198             if $self->{debug};
199              
200 1         467 undef;
201             }
202              
203             sub _child_stdout {
204 5     5   11345774 my ( $kernel, $self, $input ) = @_[ KERNEL, OBJECT, ARG0 ];
205              
206 5         78 my $session = delete $input->{sender};
207 5         16 my $event = delete $input->{event};
208              
209 5         72 $kernel->post( $session, $event, $input );
210 5         723 $kernel->refcount_decrement( $session => __PACKAGE__ );
211              
212 5         283 undef;
213             }
214              
215             sub _wheel {
216 0     0     my $obj_args = shift;
217              
218 0 0         if ( $^O eq 'MSWin32' ) {
219 0           binmode STDIN;
220 0           binmode STDOUT;
221             }
222              
223 0           my $raw;
224 0           my $size = 4096;
225 0           my $filter = POE::Filter::Reference->new;
226              
227 0           my $xkcd = WWW::XKCD::AsText->new( %$obj_args );
228              
229 0           while ( sysread STDIN, $raw, $size ) {
230 0           my $requests = $filter->get( [ $raw ] );
231 0           foreach my $req_ref ( @$requests ) {
232              
233 0           _process_request( $xkcd, $req_ref ); # changes $req_ref
234              
235 0           my $response = $filter->put( [ $req_ref ] );
236 0           print STDOUT @$response;
237             }
238             }
239             }
240              
241             sub _process_request {
242 0     0     my ( $xkcd, $req_ref ) = @_;
243 0           my $text = $xkcd->retrieve( $req_ref->{id} );
244              
245 0 0         if ( defined $text ) {
246 0           @$req_ref{ qw(uri text) } = ( $xkcd->uri, $text );
247             }
248             else {
249 0           $req_ref->{error} = $xkcd->error;
250             }
251              
252 0           undef;
253             }
254              
255              
256             1;
257             __END__