File Coverage

blib/lib/POE/Component/SmokeBox/Uploads/NNTP.pm
Criterion Covered Total %
statement 76 91 83.5
branch 11 22 50.0
condition 2 5 40.0
subroutine 16 20 80.0
pod 3 3 100.0
total 108 141 76.6


line stmt bran cond sub pod time code
1             package POE::Component::SmokeBox::Uploads::NNTP;
2              
3 2     2   255805 use strict;
  2         4  
  2         73  
4 2     2   10 use warnings;
  2         3  
  2         55  
5 2     2   10 use Carp;
  2         9  
  2         298  
6 2     2   1307 use POE qw(Component::Client::NNTP);
  2         95492  
  2         24  
7 2     2   218292 use Email::Simple;
  2         20963  
  2         167  
8 2     2   27 use vars qw($VERSION);
  2         5  
  2         2636  
9              
10             $VERSION = '1.00';
11              
12             sub spawn {
13 1     1 1 3140 my $package = shift;
14 1         8 my %opts = @_;
15 1         13 $opts{lc $_} = delete $opts{$_} for keys %opts;
16 1 50       6 croak "$package requires an 'event' argument\n" unless $opts{event};
17 1 50       5 $opts{nntp} = 'nntp.perl.org' unless $opts{nntp};
18 1 50       9 $opts{group} = 'perl.cpan.uploads' unless $opts{group};
19 1         4 my $options = delete $opts{options};
20 1         4 my $self = bless \%opts, $package;
21 1 50       36 $self->{session_id} = POE::Session->create(
22             object_states => [
23             $self => { shutdown => '_shutdown',
24             connect => '_connect',
25             poll => '_poll',
26             nntp_registered => '_nntp_registered',
27             nntp_socketerr => '_nntp_socketerr',
28             nntp_disconnected => '_nntp_disconnected',
29             nntp_200 => '_nntp_200',
30             nntp_211 => '_nntp_211',
31             nntp_220 => '_nntp_220',
32             },
33             $self => [ qw(_start _dispatch) ],
34             ],
35             heap => $self,
36             ( ref($options) eq 'HASH' ? ( options => $options ) : () ),
37             )->ID();
38 1         109 return $self;
39             }
40              
41             sub session_id {
42 0     0 1 0 return $_[0]->{session_id};
43             }
44              
45             sub shutdown {
46 0     0 1 0 my $self = shift;
47 0         0 $poe_kernel->post( $self->{session_id}, 'shutdown' );
48 0         0 return;
49             }
50              
51             sub _shutdown {
52 1     1   1142 my ($kernel,$self) = @_[KERNEL,OBJECT];
53 1         6 $kernel->alias_remove( $_ ) for $kernel->alias_list();
54 1 50       35 $kernel->refcount_decrement( $self->{session_id}, __PACKAGE__ ) unless $self->{alias};
55 1         25 $kernel->refcount_decrement( $self->{sender_id}, __PACKAGE__ );
56 1         31 $kernel->post( $self->{nntpclient}->session_id(), 'shutdown' );
57 1         85 return;
58             }
59              
60             sub _start {
61 1     1   303 my ($kernel,$session,$sender,$self) = @_[KERNEL,SESSION,SENDER,OBJECT];
62 1         4 $self->{session_id} = $session->ID();
63 1 50 33     18 if ( $kernel == $sender and !$self->{session} ) {
64 0         0 croak "Not called from another POE session and 'session' wasn't set\n";
65             }
66 1         3 my $sender_id;
67 1 50       4 if ( $self->{session} ) {
68 0 0       0 if ( my $ref = $kernel->alias_resolve( $self->{session} ) ) {
69 0         0 $sender_id = $ref->ID();
70             }
71             else {
72 0         0 croak "Could not resolve 'session' to a valid POE session\n";
73             }
74             }
75             else {
76 1         9 $sender_id = $sender->ID();
77             }
78 1         8 $kernel->refcount_increment( $sender_id, __PACKAGE__ );
79 1         26 $self->{sender_id} = $sender_id;
80 1         13 $self->{nntpclient} = POE::Component::Client::NNTP->spawn( 'nntp' . $self->{session_id},
81             { NNTPServer => $self->{nntp}, Port => $self->{nntp_port} } );
82 1         981 return;
83             }
84              
85             sub _nntp_registered {
86 1     1   204 my ($kernel,$self,$sender) = @_[KERNEL,OBJECT,SENDER];
87 1         20 $kernel->yield( 'connect', $sender->ID() );
88 1         65 return;
89             }
90              
91             sub _connect {
92 1     1   183 my ($kernel,$self,$sender) = @_[KERNEL,OBJECT,ARG0];
93 1         5 $kernel->post( $sender, 'connect' );
94 1         300 return;
95             }
96              
97             sub _nntp_socketerr {
98 0     0   0 my ($kernel,$self,$sender,$error) = @_[KERNEL,OBJECT,SENDER,ARG0];
99 0         0 warn "Socket error: $error\n";
100 0         0 $kernel->delay( 'connect', 60, $sender->ID() );
101 0         0 return;
102             }
103              
104             sub _nntp_disconnected {
105 0     0   0 my ($kernel,$self,$sender) = @_[KERNEL,OBJECT,SENDER];
106 0         0 $kernel->delay( 'connect', 60, $sender->ID() );
107 0         0 return;
108             }
109              
110             sub _poll {
111 3     3   19965578 my ($kernel,$self) = @_[KERNEL,OBJECT];
112 3         25 $kernel->post ( $self->{nntpclient}->session_id(), 'group', $self->{group} );
113 3         291 undef;
114             }
115              
116             sub _nntp_200 {
117 1     1   5476 my ($kernel,$self) = @_[KERNEL,OBJECT];
118 1         12 $kernel->yield( 'poll' );
119 1         59 undef;
120             }
121              
122             sub _nntp_211 {
123 2     2   5630 my ($kernel,$self,$sender) = @_[KERNEL,OBJECT,SENDER];
124 2         10 my ($estimate,$first,$last,$group) = split( /\s+/, $_[ARG0] );
125              
126 2 100       12 if ( defined $self->{articles}->{ $group } ) {
127             # Check for new articles
128 1 50       54 if ( $estimate >= $self->{articles}->{ $group } ) {
129 1         4 for my $article ( $self->{articles}->{ $group } .. $estimate ) {
130 1         5 $kernel->post ( $sender => article => $article );
131             }
132 1         84 $self->{articles}->{ $group } = $estimate + 1;
133             }
134             }
135             else {
136 1         6 $self->{articles}->{ $group } = $estimate + 1;
137             }
138 2   50     23 $kernel->delay( 'poll' => ( $self->{poll} || 60 ) );
139 2         161 undef;
140             }
141              
142             sub _nntp_220 {
143 1     1   49660 my ($kernel,$self,$text) = @_[KERNEL,OBJECT,ARG0];
144 1         3 my $article = Email::Simple->new( join "\n", @{ $_[ARG1] } );
  1         33  
145 1         1779 my $subject = $article->header('Subject');
146 1 50       85 if ( my ($upload) = $subject =~ m!^CPAN Upload:\s+(\w+/\w+/\w+/.+(\.tar\.(gz|bz2)|\.tgz|\.zip))$!i ) {
147 1         7 $kernel->call( $self->{session_id}, '_dispatch', $upload );
148             }
149 1         34 return;
150             }
151              
152             sub _dispatch {
153 1     1   46 my ($kernel,$self,$module) = @_[KERNEL,OBJECT,ARG0];
154 1         6 $kernel->post( $self->{sender_id}, $self->{event}, $module );
155 1         107 return;
156             }
157              
158             1;
159             __END__