File Coverage

blib/lib/POE/Component/Archive/Any.pm
Criterion Covered Total %
statement 67 114 58.7
branch 16 50 32.0
condition 2 9 22.2
subroutine 13 18 72.2
pod 4 4 100.0
total 102 195 52.3


line stmt bran cond sub pod time code
1             package POE::Component::Archive::Any;
2              
3 2     2   449847 use warnings;
  2         6  
  2         73  
4 2     2   10 use strict;
  2         3  
  2         79  
5              
6             our $VERSION = '0.002';
7              
8 2     2   10 use Carp;
  2         7  
  2         114  
9 2     2   10 use POE (qw( Filter::Reference Filter::Line Wheel::Run ));
  2         3  
  2         27  
10              
11             sub spawn {
12 1     1 1 14 my $package = shift;
13 1 50       4 croak "$package requires an even number of arguments"
14             if @_ & 1;
15              
16 1         5 my %params = @_;
17            
18 1         8 $params{ lc $_ } = delete $params{ $_ } for keys %params;
19              
20 1 50       6 delete $params{options}
21             unless ref $params{options} eq 'HASH';
22            
23 1         3 my $self = bless \%params, $package;
24              
25 1 50       19 $self->{session_id} = POE::Session->create(
26             object_states => [
27             $self => {
28             extract => '_extract',
29             shutdown => '_shutdown',
30             },
31             $self => [
32             qw(
33             _child_error
34             _child_closed
35             _child_stdout
36             _child_stderr
37             _sig_child
38             _start
39             )
40             ]
41             ],
42             ( defined $params{options} ? ( options => $params{options} ) : () ),
43             )->ID();
44              
45 1         331 return $self;
46             }
47              
48              
49             sub _start {
50 1     1   278 my ( $kernel, $self ) = @_[ KERNEL, OBJECT ];
51 1         4 $self->{session_id} = $_[SESSION]->ID();
52              
53 1 50       8 if ( $self->{alias} ) {
54 0         0 $kernel->alias_set( $self->{alias} );
55             }
56             else {
57 1         8 $kernel->refcount_increment( $self->{session_id} => __PACKAGE__ );
58             }
59              
60 1 50       41 $self->{wheel} = POE::Wheel::Run->new(
61             Program => \&_wheel,
62             ErrorEvent => '_child_error',
63             CloseEvent => '_child_close',
64             StdoutEvent => '_child_stdout',
65             StderrEvent => '_child_stderr',
66             StdioFilter => POE::Filter::Reference->new,
67             StderrFilter => POE::Filter::Line->new,
68             ( $^O eq 'MSWin32' ? ( CloseOnCall => 0 ) : ( CloseOnCall => 1 ) )
69             );
70              
71 1 50       5416 $kernel->yield('shutdown')
72             unless $self->{wheel};
73              
74 1         40 $kernel->sig_child( $self->{wheel}->PID(), '_sig_child' );
75              
76 1         363 undef;
77             }
78              
79             sub _sig_child {
80 1     1   962 $poe_kernel->sig_handled;
81             }
82              
83             sub session_id {
84 0     0 1 0 return $_[0]->{session_id};
85             }
86              
87             sub extract {
88 1     1 1 2419 my $self = shift;
89 1         11 $poe_kernel->post( $self->{session_id} => 'extract' => @_ );
90             }
91              
92             sub _extract {
93 1     1   595 my ( $kernel, $self ) = @_[ KERNEL, OBJECT ];
94 1         18 my $sender = $_[SENDER]->ID;
95            
96             return
97 1 50       15 if $self->{shutdown};
98            
99 1         2 my $args;
100 1 50       6 if ( ref $_[ARG0] eq 'HASH' ) {
101 1         2 $args = { %{ $_[ARG0] } };
  1         6  
102             }
103             else {
104 0         0 carp "First parameter must be a hashref, trying to adjust...";
105 0         0 $args = { @_[ARG0 .. $#_] };
106             }
107            
108 4         34 $args->{ lc $_ } = delete $args->{ $_ }
109 1         7 for grep { !/^_/ } keys %$args;
110              
111 1 50       5 unless ( $args->{event} ) {
112 0         0 carp "Missing 'event' parameter to extract";
113 0         0 return;
114             }
115 1 50       9 unless ( $args->{file} ) {
116 0         0 carp "Missing 'file' parameter to extract";
117 0         0 return;
118             }
119              
120 1 50 33     61 if ( defined $args->{dir}
      33        
121             and not defined $args->{just_info}
122             and not -e $args->{dir}
123             ) {
124 0 0       0 unless ( mkdir $args->{dir} ) {
125 0         0 carp "Directory `$args->{dir}` did not exist and I failed"
126             . "to create it ($!)";
127 0         0 return;
128             }
129             }
130            
131 1 50       18 if ( $args->{session} ) {
132 0 0       0 if ( my $ref = $kernel->alias_resolve( $args->{session} ) ) {
133 0         0 $args->{sender} = $ref->ID;
134             }
135             else {
136 0         0 carp "Could not resolve 'session' parameter to a valid"
137             . " POE session";
138 0         0 return;
139             }
140             }
141             else {
142 1         8 $args->{sender} = $sender;
143             }
144            
145 1         10 $kernel->refcount_increment( $args->{sender} => __PACKAGE__ );
146 1         51 $self->{wheel}->put( $args );
147            
148 1         298 undef;
149             }
150              
151             sub shutdown {
152 1     1 1 4652 my $self = shift;
153 1         9 $poe_kernel->call( $self->{session_id} => 'shutdown' => @_ );
154             }
155              
156             sub _shutdown {
157 1     1   125 my ( $kernel, $self ) = @_[ KERNEL, OBJECT ];
158 1         57 $kernel->alarm_remove_all;
159 1         104 $kernel->alias_remove( $_ ) for $kernel->alias_list;
160 1 50       43 $kernel->refcount_decrement( $self->{session_id} => __PACKAGE__ )
161             unless $self->{alias};
162              
163 1         51 $self->{shutdown} = 1;
164            
165 1 50       33 $self->{wheel}->shutdown_stdin
166             if $self->{wheel};
167             }
168              
169             sub _child_closed {
170 0     0   0 my ( $kernel, $self ) = @_[ KERNEL, OBJECT ];
171            
172 0 0       0 carp "_child_closed called (@_[ARG0..$#_])\n"
173             if $self->{debug};
174              
175 0         0 delete $self->{wheel};
176 0 0       0 $kernel->yield('shutdown')
177             unless $self->{shutdown};
178              
179 0         0 undef;
180             }
181              
182             sub _child_error {
183 1     1   2459 my ( $kernel, $self ) = @_[ KERNEL, OBJECT ];
184 1 50       780 carp "_child_error called (@_[ARG0..$#_])\n"
185             if $self->{debug};
186              
187 1         407 delete $self->{wheel};
188 1 50       793 $kernel->yield('shutdown')
189             unless $self->{shutdown};
190              
191 1         5 undef;
192             }
193              
194             sub _child_stderr {
195 0     0   0 my ( $kernel, $self ) = @_[ KERNEL, OBJECT ];
196 0 0       0 carp "_child_stderr: $_[ARG0]\n"
197             if $self->{debug};
198              
199 0         0 undef;
200             }
201              
202             sub _child_stdout {
203 1     1   2759135 my ( $kernel, $self, $input ) = @_[ KERNEL, OBJECT, ARG0 ];
204            
205 1         5 my $session = delete $input->{sender};
206 1         4 my $event = delete $input->{event};
207              
208 1         6 $kernel->post( $session, $event, $input );
209 1         155 $kernel->refcount_decrement( $session => __PACKAGE__ );
210            
211 1         81 undef;
212             }
213              
214             sub _wheel {
215 0 0   0     if ( $^O eq 'MSWin32' ) {
216 0           binmode STDIN;
217 0           binmode STDOUT;
218             }
219            
220 0           my $raw;
221 0           my $size = 4096;
222 0           my $filter = POE::Filter::Reference->new;
223              
224 0           while ( sysread STDIN, $raw, $size ) {
225 0           my $requests = $filter->get( [ $raw ] );
226 0           foreach my $req_ref ( @$requests ) {
227              
228 0           _process_request( $req_ref ); # changes $req_ref
229              
230 0           my $response = $filter->put( [ $req_ref ] );
231 0           print STDOUT @$response;
232             }
233             }
234             }
235              
236             sub _process_request {
237 0     0     my $req_ref = shift;
238 0           require Archive::Any;
239 0           my $ar = Archive::Any->new( $req_ref->{file} );
240 0 0         unless ( defined $ar ) {
241 0           $req_ref->{error} = 'Failed to create the '
242             . 'Archive::Any object.';
243              
244 0 0         unless ( -f $req_ref->{file} ) {
245 0           $req_ref->{error} .= q| Specified `file` doesn't exist|;
246             }
247 0           return;
248             }
249              
250 0 0         unless ( $req_ref->{just_info} ) {
251 0           $ar->extract( $req_ref->{dir} );
252             }
253            
254 0   0       @$req_ref{ qw(files type is_impolite is_naughty) }
255             = (
256             [ $ar->files ],
257              
258             ## TODO when the bug in Archive::Any is fixed, change this to
259             ## simple $ar->mime->type()
260             ($ar->{type} || $ar->mime_type ),
261             scalar $ar->is_impolite,
262             scalar $ar->is_naughty,
263             );
264              
265 0           undef;
266             }
267              
268              
269             1;
270             __END__