File Coverage

blib/lib/POE/Component/MetaCPAN/Recent.pm
Criterion Covered Total %
statement 83 93 89.2
branch 15 34 44.1
condition 2 6 33.3
subroutine 15 16 93.7
pod 3 3 100.0
total 118 152 77.6


line stmt bran cond sub pod time code
1             package POE::Component::MetaCPAN::Recent;
2             $POE::Component::MetaCPAN::Recent::VERSION = '1.00';
3             #ABSTRACT: Obtain uploaded CPAN dists via MetaCPAN.
4              
5 1     1   1142 use strict;
  1         3  
  1         29  
6 1     1   5 use warnings;
  1         2  
  1         24  
7 1     1   5 use Carp;
  1         2  
  1         59  
8 1     1   7 use POE qw[Component::Client::HTTP];
  1         3  
  1         9  
9 1     1   110952 use HTTP::Request;
  1         1562  
  1         32  
10 1     1   9 use HTTP::Response;
  1         3  
  1         22  
11 1     1   752 use JSON::PP;
  1         14241  
  1         83  
12 1     1   593 use Time::Piece;
  1         10464  
  1         8  
13              
14             sub spawn {
15 1     1 1 864 my $package = shift;
16 1         4 my %opts = @_;
17 1         7 $opts{lc $_} = delete $opts{$_} for keys %opts;
18 1 50       5 croak "$package requires an 'event' argument\n" unless $opts{event};
19 1 50       4 $opts{delay} = 180 unless $opts{delay};
20 1         3 my $options = delete $opts{options};
21 1         2 my $self = bless \%opts, $package;
22 1 50       13 $self->{session_id} = POE::Session->create(
23             object_states => [
24             $self => { shutdown => '_shutdown', },
25             $self => [ qw(_start _get_recent _handle_recent _real_shutdown) ],
26             ],
27             heap => $self,
28             ( ref($options) eq 'HASH' ? ( options => $options ) : () ),
29             )->ID();
30 1         124 return $self;
31             }
32              
33             sub session_id {
34 1     1 1 9577519 return $_[0]->{session_id};
35             }
36              
37             sub shutdown {
38 0     0 1 0 my $self = shift;
39 0         0 $poe_kernel->post( $self->{session_id}, 'shutdown' );
40 0         0 return;
41             }
42              
43             sub _shutdown {
44 1     1   207 my ($kernel,$self) = @_[KERNEL,OBJECT];
45 1         15 $self->{_shutdown} = 1;
46 1 50       7 return if $self->{_http_requests};
47 1         12 $kernel->yield( '_real_shutdown' );
48 1         85 return;
49             }
50              
51             sub _real_shutdown {
52 1     1   160 my ($kernel,$self) = @_[KERNEL,OBJECT];
53 1         14 $kernel->alarm_remove_all();
54 1         161 $kernel->alias_remove( $_ ) for $kernel->alias_list();
55 1 50       49 $kernel->refcount_decrement( $self->{session_id}, __PACKAGE__ ) unless $self->{alias};
56 1         42 $kernel->refcount_decrement( $self->{sender_id}, __PACKAGE__ );
57 1 50       50 $kernel->post( $self->{http_id}, 'shutdown' ) unless $self->{http_alias};
58 1         124 return;
59             }
60              
61             sub _start {
62 1     1   295 my ($kernel,$session,$sender,$self) = @_[KERNEL,SESSION,SENDER,OBJECT];
63 1         10 $self->{session_id} = $session->ID();
64 1 50 33     10 if ( $kernel == $sender and !$self->{session} ) {
65 0         0 croak "Not called from another POE session and 'session' wasn't set\n";
66             }
67 1         19 my $sender_id;
68 1 50       5 if ( $self->{session} ) {
69 0 0       0 if ( my $ref = $kernel->alias_resolve( $self->{session} ) ) {
70 0         0 $sender_id = $ref->ID();
71             }
72             else {
73 0         0 croak "Could not resolve 'session' to a valid POE session\n";
74             }
75             }
76             else {
77 1         4 $sender_id = $sender->ID();
78             }
79 1         10 $kernel->refcount_increment( $sender_id, __PACKAGE__ );
80 1         46 $self->{sender_id} = $sender_id;
81 1 50       4 if ( $self->{http_alias} ) {
82 0         0 my $http_ref = $kernel->alias_resolve( $self->{http_alias} );
83 0 0       0 $self->{http_id} = $http_ref->ID() if $http_ref;
84             }
85 1 50       3 unless ( $self->{http_id} ) {
86 1         6 $self->{http_id} = 'metacpanr' . $$ . $self->{session_id};
87             POE::Component::Client::HTTP->spawn(
88             Alias => $self->{http_id},
89 1         11 FollowRedirects => 2,
90             Timeout => 60,
91             Agent => 'Mozilla/5.0 (X11; U; Linux i686; en-US; '
92             . 'rv:1.1) Gecko/20020913 Debian/1.1-1',
93             );
94             }
95 1         2072 $self->{timestamp} = time();
96             # Start requesting
97 1         6 $kernel->yield('_get_recent');
98 1         67 return;
99             }
100              
101             sub _get_recent {
102 1     1   1497 my ($kernel,$self) = @_[KERNEL,OBJECT];
103 1         4 $kernel->delay('_get_recent');
104             $kernel->post(
105             $self->{http_id},
106 1         77 'request',
107             '_handle_recent',
108             HTTP::Request->new( GET => 'http://fastapi.metacpan.org/release/recent?type=l&page=1&page_size=100' ),
109             );
110 1         7716 $self->{_http_requests}++;
111 1         6 return;
112             }
113              
114             sub _handle_recent {
115 1     1   218056 my ($kernel,$self,$req,$res) = @_[KERNEL,OBJECT,ARG0,ARG1];
116 1         4 $self->{_http_requests}--;
117 1         8 my $http_resp = $res->[0];
118 1 50 33     61 if ( $http_resp and $http_resp->code() == 200 ) {
119 1         22 my $recents = eval { decode_json( $http_resp->content() ) };
  1         15  
120             SWITCH: {
121 1 50       204618 last SWITCH unless $recents;
  1         13  
122 1 50       16 last SWITCH unless $recents->{releases};
123 1 50       8 last SWITCH unless ref $recents->{releases} eq 'ARRAY';
124 1         8 foreach my $recent ( @{ $recents->{releases} } ) {
  1         14  
125 1         46 my $ts = Time::Piece->strptime($recent->{date},"%Y-%m-%dT%H:%M:%S")->epoch;
126 1 50       357 last SWITCH if $ts < $self->{timestamp};
127 0         0 $kernel->post( $self->{sender_id}, $self->{event}, $recent );
128             }
129             }
130             }
131 1         104 $self->{timestamp} = time();
132 1         14 $kernel->delay('_get_recent', $self->{delay});
133 1         282 return;
134             }
135              
136             "Fooby Dooby Foo Bar";
137              
138             __END__