File Coverage

blib/lib/WebService/ChangesXml.pm
Criterion Covered Total %
statement 22 24 91.6
branch n/a
condition n/a
subroutine 8 8 100.0
pod n/a
total 30 32 93.7


line stmt bran cond sub pod time code
1             package WebService::ChangesXml;
2              
3 3     3   70504 use strict;
  3         8  
  3         136  
4 3     3   17 use vars qw($VERSION);
  3         6  
  3         223  
5             $VERSION = '0.01';
6              
7 3     3   20 use Carp;
  3         10  
  3         414  
8 3     3   3517 use LWP::UserAgent;
  3         181287  
  3         107  
9 3     3   37 use HTTP::Date;
  3         5  
  3         456  
10 3     3   16 use HTTP::Request;
  3         6  
  3         66  
11 3     3   16 use HTTP::Status;
  3         10  
  3         1171  
12 3     3   1616 use XML::Simple;
  0            
  0            
13              
14             sub new {
15             my($class, $url) = @_;
16             defined($url) or croak "Usage: new(\$url)";
17             my $self = bless { url => $url }, $class;
18             $self->_init_ua();
19             return $self;
20             }
21              
22             sub _init_ua {
23             my $self = shift;
24             $self->{ua} = LWP::UserAgent->new();
25             $self->{ua}->agent("WebService::ChangesXml/$VERSION");
26             }
27              
28             sub user_agent { shift->{ua} }
29             sub url { shift->{url} }
30             sub count { shift->{count} }
31              
32             sub updated {
33             my $self = shift;
34             $self->{updated} = shift if @_;
35             $self->{updated};
36             }
37              
38             sub add_handler {
39             my($self, $sub) = @_;
40             defined($sub) and ref($sub) eq 'CODE' or croak "Usage: add_handler(\$subref);";
41             push @{$self->{handlers}}, $sub;
42             }
43              
44             sub find_new_pings {
45             my $self = shift;
46              
47             my $simple_api;
48             if (@_) {
49             $simple_api = 1;
50              
51             # set updated with $interval
52             my $interval = shift;
53             $self->{updated} = time - $interval;
54             }
55              
56             # HTTP/GET changes.xml
57             my $request = HTTP::Request->new(GET => $self->url);
58             if (defined($self->{updated})) {
59             $request->header('If-Modified-Since' => HTTP::Date::time2str($self->{updated}));
60             }
61             my $response = $self->user_agent->request($request);
62             die "Got error in fetching changes.xml: ", $response->code unless $response->is_success;
63              
64             # do nothing if changes.xml is not modified
65             if ($response->code == RC_NOT_MODIFIED) {
66             return $simple_api ? [] : 1;
67             }
68              
69             my $xml = $response->content();
70             my $p = XML::Simple->new();
71             my $updates = $p->XMLin($xml, KeyAttr => 'weblog', ForceArray => 1);
72              
73             # set updated and count
74             my $old = $self->{updated} || 0;
75             $self->{updated} = HTTP::Date::str2time($updates->{updated})
76             or croak "weird updated format: $updates->{updated}";
77             $self->{count} = $updates->{count};
78              
79             my @pings;
80             for my $weblog (@{$updates->{weblog}}) {
81             # calculate "when" to Unix time
82             my $when = $self->{updated} - $weblog->{when};
83              
84             # no more new blogs
85             last if $old >= $self->{updated} - $weblog->{when};
86              
87             if ($simple_api) {
88             push @pings, { name => $weblog->{name},
89             url => $weblog->{url},
90             when => $when };
91             } else {
92             for my $handler (@{$self->{handlers}}) {
93             $handler->($weblog->{name}, $weblog->{url}, $when);
94             }
95             }
96             }
97              
98             return $simple_api ? \@pings : 1;
99             }
100              
101             1;
102             __END__