File Coverage

blib/lib/WWW/Ohloh/API/Projects.pm
Criterion Covered Total %
statement 30 74 40.5
branch 0 18 0.0
condition 0 5 0.0
subroutine 11 16 68.7
pod 2 3 66.6
total 43 116 37.0


line stmt bran cond sub pod time code
1             package WWW::Ohloh::API::Projects;
2             our $AUTHORITY = 'cpan:YANICK';
3              
4 29     29   156198 use strict;
  29         60  
  29         1167  
5 29     29   139 use warnings;
  29         59  
  29         1661  
6              
7 29     29   158 use Carp;
  29         72  
  29         2094  
8 29     29   922 use Object::InsideOut;
  29         42559  
  29         220  
9 29     29   3686 use XML::LibXML;
  29         35023  
  29         238  
10 29     29   5937 use Readonly;
  29         3964  
  29         1990  
11 29     29   17427 use List::MoreUtils qw/ none any /;
  29         466719  
  29         256  
12              
13 29     29   44107 use overload '<>' => \&next;
  29         78  
  29         328  
14              
15             our $VERSION = '1.0_1';
16              
17             my @all_read : Field : Default(0);
18             my @cache_of : Field;
19             my @total_entries_of : Field : Default(-1);
20             my @ohloh_of : Field : Arg(ohloh);
21             my @page_of : Field : Default(0);
22             my @query_of : Field : Arg(query);
23             my @sort_order_of : Field : Arg(sort) :
24             Type(\&WWW::Ohloh::API::Projects::is_allowed_sort);
25             my @max_entries_of : Field : Arg(max) : Get(max);
26              
27             Readonly our @ALLOWED_SORTING => map { $_, $_ . '_reverse' }
28             qw/ created_at description id name stack_count updated_at /;
29              
30             #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
31              
32             sub is_allowed_sort {
33 1     1 0 2035 my $s = shift;
34 1     12   16 return any { $s eq $_ } @ALLOWED_SORTING;
  12         84  
35             }
36              
37             sub _init : Init {
38 0     0     my $self = shift;
39              
40 0           $cache_of[$$self] = []; # initialize to empty array
41              
42 0 0         if ( my $s = $sort_order_of[$$self] ) {
43 0 0   0     if ( none { $s eq $_ } @ALLOWED_SORTING ) {
  0            
44 0           croak "sorting order given: $s, must be one of the following: "
45             . join ', ' => @ALLOWED_SORTING;
46             }
47             }
48 29     29   13332 }
  29         68  
  29         317  
49              
50             #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
51              
52             sub next {
53 0     0 1   my $self = shift;
54 0   0       my $nbr_requested = shift || 1;
55              
56 0   0       while ( @{ $cache_of[$$self] } < $nbr_requested
  0            
57             and not $all_read[$$self] ) {
58 0           $self->_gather_more;
59             }
60              
61 0           my @bunch = splice @{ $cache_of[$$self] }, 0, $nbr_requested;
  0            
62              
63 0 0         if (@bunch) {
64 0 0         return wantarray ? @bunch : $bunch[0];
65             }
66              
67             # we've nothing else to return
68              
69 0           $page_of[$$self] = 0;
70 0           $all_read[$$self] = 0;
71              
72 0           return;
73             }
74              
75             #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
76              
77             sub _gather_more {
78 0     0     my $self = shift;
79              
80 0           my ( $url, $xml ) = $ohloh_of[$$self]->_query_server(
81             'projects.xml',
82             { ( query => $query_of[$$self] ) x !!$query_of[$$self],
83             ( sort => $sort_order_of[$$self] ) x !!$sort_order_of[$$self],
84             page => ++$page_of[$$self] } );
85              
86             my @new_batch =
87             map {
88 0           WWW::Ohloh::API::Project->new(
  0            
89             ohloh => $ohloh_of[$$self],
90             xml => $_,
91             )
92             } $xml->findnodes('project');
93              
94             # get total projects + where we are
95              
96 0           $total_entries_of[$$self] =
97             $xml->findvalue('/response/items_available/text()');
98              
99 0           my $first_item = $xml->findvalue('/response/first_item_position/text()');
100              
101 0 0         $all_read[$$self] = 1 unless $total_entries_of[$$self];
102              
103 0 0         if ( $first_item + @new_batch - 1 >= $total_entries_of[$$self] ) {
104 0           $all_read[$$self] = 1;
105             }
106              
107 0 0         if ( my $max = $self->max ) {
108 0 0         if ( $first_item + @new_batch - 1 >= $max ) {
109 0           @new_batch = splice @new_batch, 0, $max - $first_item;
110 0           $all_read[$$self] = 1;
111             }
112             }
113              
114 0           push @{ $cache_of[$$self] }, @new_batch;
  0            
115              
116 0           return;
117             }
118              
119             #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
120              
121             sub all {
122 0     0 1   my $self = shift;
123              
124 0 0         unless ( $self->max ) {
125 0           croak "call to all only permitted if 'max' set in get_projects()";
126             }
127              
128 0           $self->_gather_more until ( $all_read[$$self] );
129              
130 0           my @bunch = @{ $cache_of[$$self] };
  0            
131 0           $cache_of[$$self] = [];
132              
133 0           $page_of[$$self] = 0;
134 0           $all_read[$$self] = 0;
135              
136 0           return @bunch;
137             }
138              
139             'end of WWW::Ohloh::API::Projects';
140              
141             __END__