File Coverage

blib/lib/WebService/Hatena/BookmarkCount.pm
Criterion Covered Total %
statement 58 77 75.3
branch 19 64 29.6
condition 2 5 40.0
subroutine 7 9 77.7
pod 2 5 40.0
total 88 160 55.0


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             WebService::Hatena::BookmarkCount -- Interface for Hatena::Bookmark's XML-RPC API
4              
5             =head1 SYNOPSIS
6              
7             use WebService::Hatena::BookmarkCount;
8              
9             my @list = (
10             'http://www.hatena.ne.jp/info/webservices',
11             'http://www.kawa.net/works/perl/hatena/bookmarkcount.html',
12             );
13             my $hash = WebService::Hatena::BookmarkCount->getCount( @list );
14             foreach my $url ( @list ) {
15             printf( "%5d %s\n", $hash->{$url}, $url );
16             }
17              
18             my $top = 'http://japan.cnet.com/';
19             my $total = WebService::Hatena::BookmarkCount->getTotalCount( $top );
20              
21             =head1 DESCRIPTION
22              
23             WebService::Hatena::BookmarkCount is a interface for the Hatena::Bookmark
24             Web Services's XML-RPC API. This provides two methods, I
25             and I, to get numbers of count on bookmarks.
26              
27             =head1 METHODS
28              
29             =head3 $hash = WebService::Hatena::BookmarkCount->getCount( @list );
30              
31             This method makes a I XML-RPC call for the Hatena::Bookmark
32             Web Services. C<@list> is list of URLs to get a number of registrations in
33             Hatena::Bookmark. This method returns a reference for a hash, which keys are
34             URLs and which values are counts returned by the Hatena Web Services.
35              
36             =head3 $hash = WebService::Hatena::BookmarkCount->getTotalCount( $url );
37              
38             This method makes a I XML-RPC call for
39             the Hatena::Bookmark Web Services. C<$url> is the URL to get a number of
40             registrations in Hatena::Bookmark.
41              
42             =head1 MODULE DEPENDENCIES
43              
44             L
45              
46             L or L
47              
48             =head1 SEE ALSO
49              
50             Hatena Bookmark
51             http://b.hatena.ne.jp/
52              
53             Documents in Japanese
54             http://www.kawa.net/works/perl/hatena/bookmarkcount.html
55              
56             =head1 AUTHOR
57              
58             Yusuke Kawasaki http://www.kawa.net/
59              
60             =head1 COPYRIGHT
61              
62             The following copyright notice applies to all the files provided in
63             this distribution, including binary files, unless explicitly noted
64             otherwise.
65              
66             Copyright 2006-2010 Yusuke Kawasaki
67              
68             =head1 LICENSE
69              
70             This library is free software; you can redistribute it and/or modify
71             it under the same terms as Perl itself.
72              
73             =cut
74              
75             package WebService::Hatena::BookmarkCount;
76 2     2   25578 use strict;
  2         6  
  2         77  
77 2     2   11 use Carp;
  2         4  
  2         171  
78 2     2   4139 use XML::TreePP;
  2         20662  
  2         88  
79              
80 2     2   23 use vars qw( $VERSION );
  2         5  
  2         2377  
81             $VERSION = "0.07";
82              
83             my $XMLRPC_URL = 'http://b.hatena.ne.jp/xmlrpc';
84             my $WAIT_SECS = 1;
85             my $MAX_REQUEST = 40;
86             my $TREEPP_OPTIONS = { force_array => [qw( member )] };
87              
88             sub new {
89 1     1 0 3 my $package = shift;
90 1         3 my $self = {@_};
91 1         2 bless $self, $package;
92 1         13 $self->{treepp} = XML::TreePP->new(%$TREEPP_OPTIONS);
93 1         15 $self;
94             }
95              
96             sub getCount {
97 1 50   1 1 18 my $self = shift or return;
98 1 50       9 $self = $self->new() unless ref $self;
99 1         3 my $links = [@_]; # copy
100              
101 1         3 my $outhash = {};
102 1         2 my $reqxml;
103             my $resxml;
104 1         3 my $sleep = $WAIT_SECS;
105 1         3 my $tpp = $self->{treepp};
106 1         6 while ( scalar @$links ) {
107 1         5 my @splice = splice( @$links, 0, $MAX_REQUEST );
108 1         3 my $param = [ map { { value => { string => $_ } }; } @splice ];
  1         8  
109 1         7 my $reqtree = {
110             methodCall => {
111             methodName => "bookmark.getCount",
112             params => { param => $param }
113             }
114             };
115 1 50       6 $reqxml = $tpp->write($reqtree) or last;
116 1         15451 my $tree;
117 1         9 ( $tree, $resxml ) = $tpp->parsehttp( POST => $XMLRPC_URL, $reqxml );
118 1 50       1096310 last unless ref $tree;
119 1         5 &parse_res_struct( $tree, $outhash );
120 1 50       20 sleep( $sleep++ ) if scalar @$links; # wait
121             }
122 1 50       5 $outhash = undef unless scalar keys %$outhash;
123 1 0 33     4 return if ( !$outhash && !wantarray );
124 1 50       22 wantarray ? ( $outhash, $reqxml, $resxml ) : $outhash;
125             }
126              
127             sub getTotalCount {
128 0 0   0 1 0 my $self = shift or return;
129 0 0       0 $self = $self->new() unless ref $self;
130 0 0       0 my $url = shift or return;
131              
132 0         0 my $reqtree = {
133             methodCall => {
134             methodName => "bookmark.getTotalCount",
135             params => {
136             param => {
137             value => {
138             string => $url,
139             }
140             }
141             }
142             }
143             };
144              
145 0         0 my $tpp = $self->{treepp};
146 0 0       0 my $reqxml = $tpp->write($reqtree) or last;
147 0         0 my( $tree, $resxml ) = $tpp->parsehttp( POST => $XMLRPC_URL, $reqxml );
148 0 0       0 return unless ref $tree;
149 0         0 my $count = &parse_res_simple( $tree );
150              
151 0 0       0 wantarray ? ( $count, $reqxml, $resxml ) : $count;
152             }
153              
154             sub parse_res_struct {
155 1 50   1 0 7 my $tree = shift or return;
156 1   50     6 my $hash = shift || {};
157 1 50       4 return unless ref $tree;
158 1 50       5 return unless ref $tree->{methodResponse};
159 1 50       6 return unless ref $tree->{methodResponse}->{params};
160 1 50       6 return unless ref $tree->{methodResponse}->{params}->{param};
161 1         3 my $param = $tree->{methodResponse}->{params}->{param};
162 1 50       5 return unless ref $param->{value};
163 1 50       4 return unless ref $param->{value}->{struct};
164 1         3 my $array = $param->{value}->{struct}->{member};
165 1 50       5 return unless ref $array;
166 1 50       4 return unless scalar @$array;
167              
168 1         10 foreach my $member (@$array) {
169 1 50       4 next unless defined $member->{name};
170 1 50       5 next unless ref $member->{value};
171 1         2 my $name = $member->{name};
172 1         3 my $value = $member->{value};
173 1 50       8 my $type = ( sort keys %$value )[0] or next; # first value
174 1         34 $hash->{$name} = $value->{$type};
175             }
176 1         4 $hash;
177             }
178              
179             sub parse_res_simple {
180 0 0   0 0   my $tree = shift or return;
181 0 0         return unless ref $tree;
182 0 0         return unless ref $tree->{methodResponse};
183 0 0         return unless ref $tree->{methodResponse}->{params};
184 0 0         return unless ref $tree->{methodResponse}->{params}->{param};
185 0           my $param = $tree->{methodResponse}->{params}->{param};
186 0 0         return unless ref $param->{value};
187 0           my $int = $param->{value}->{int};
188 0           $int;
189             }
190              
191             1;