|  line  | 
 stmt  | 
 bran  | 
 cond  | 
 sub  | 
 pod  | 
 time  | 
 code  | 
| 
1
 | 
  
3
  
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
27
 | 
 use strictures;  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
    | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
30
 | 
    | 
| 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 package WebService::GoogleAPI::Client::Discovery;  | 
| 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 our $VERSION = '0.26';    # VERSION  | 
| 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # ABSTRACT: Google API discovery service  | 
| 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
10
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
781
 | 
 use Moo;  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
19
 | 
    | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21
 | 
    | 
| 
11
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
1028
 | 
 use Carp;  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
17
 | 
    | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
207
 | 
    | 
| 
12
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
21
 | 
 use WebService::GoogleAPI::Client::UserAgent;  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
    | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
    | 
| 
13
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
133
 | 
 use List::Util qw/uniq reduce/;  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
    | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
228
 | 
    | 
| 
14
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
1717
 | 
 use List::SomeUtils qw/pairwise/;  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
28648
 | 
    | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
293
 | 
    | 
| 
15
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
26
 | 
 use Data::Dump qw/pp/;  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
    | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
135
 | 
    | 
| 
16
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
1357
 | 
 use CHI;  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
79244
 | 
    | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7834
 | 
    | 
| 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 has ua => (  | 
| 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   is      => 'rw',  | 
| 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   default => sub { WebService::GoogleAPI::Client::UserAgent->new }  | 
| 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 );  | 
| 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 has debug => (is => 'rw', default => 0);  | 
| 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 has 'chi' => (  | 
| 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   is      => 'rw',  | 
| 
25
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   default => sub { CHI->new(driver => 'File', namespace => __PACKAGE__) },  | 
| 
26
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   lazy    => 1  | 
| 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 );    ## i believe that this gives priority to param if provided ?  | 
| 
28
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 has 'stats' => is => 'rw',  | 
| 
29
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   default   => sub { { network => { get => 0 }, cache => { get => 0 } } };  | 
| 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub get_with_cache {  | 
| 
33
 | 
32
 | 
 
 | 
 
 | 
  
32
  
 | 
  
1
  
 | 
123
 | 
   my ($self, $key, $force, $authorized) = @_;  | 
| 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
35
 | 
32
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
878
 | 
   my $expiration = $self->chi->get_expires_at($key) // 0;  | 
| 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
37
 | 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22355
 | 
   my $will_expire = $expiration - time();  | 
| 
38
 | 
32
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
248
 | 
   if ($will_expire > 0 && not $force) {  | 
| 
39
 | 
24
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
136
 | 
     carp "discovery_data cached data expires in $will_expire seconds"  | 
| 
40
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       if $self->debug > 2;  | 
| 
41
 | 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
684
 | 
     my $ret = $self->chi->get($key);  | 
| 
42
 | 
24
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
39468
 | 
     croak 'was expecting a HASHREF!' unless ref $ret eq 'HASH';  | 
| 
43
 | 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
145
 | 
     $self->stats->{cache}{get}++;  | 
| 
44
 | 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
179
 | 
     return $ret;  | 
| 
45
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } else {  | 
| 
46
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
     my $ret;  | 
| 
47
 | 
8
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
29
 | 
     if ($authorized) {  | 
| 
48
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
       $ret = $self->ua->validated_api_query($key);  | 
| 
49
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
17
 | 
       $self->stats->{network}{authorized}++;  | 
| 
50
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } else {  | 
| 
51
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
91
 | 
       $ret = $self->ua->get($key)->res;  | 
| 
52
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
53
 | 
8
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
1741581
 | 
     if ($ret->is_success) {  | 
| 
54
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
179
 | 
       my $all = $ret->json;  | 
| 
55
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1040269
 | 
       $self->stats->{network}{get}++;  | 
| 
56
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
431
 | 
       $self->chi->set($key, $all, '30d');  | 
| 
57
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
28524
 | 
       return $all;  | 
| 
58
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } else {  | 
| 
59
 | 
  
0
  
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
       if ($ret->code == 403 && !$authorized) {  | 
| 
60
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         return $self->get_with_cache($key, $force, 1);  | 
| 
61
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
62
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       croak $ret->message;  | 
| 
63
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
64
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
65
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   return {};  | 
| 
66
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
68
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
69
 | 
12
 | 
 
 | 
 
 | 
  
12
  
 | 
  
0
  
 | 
152874
 | 
 sub discover_key { 'https://www.googleapis.com/discovery/v1/apis' }  | 
| 
70
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
71
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub discover_all {  | 
| 
72
 | 
10
 | 
 
 | 
 
 | 
  
10
  
 | 
  
1
  
 | 
311359
 | 
   my $self = shift;  | 
| 
73
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
44
 | 
   $self->get_with_cache($self->discover_key, @_);  | 
| 
74
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
75
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
76
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #TODO- double triple check that we didn't break anything with the  | 
| 
77
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #hashref change  | 
| 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
79
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
80
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #TODO- maybe cache this on disk too?  | 
| 
81
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my $available;  | 
| 
82
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
83
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _invalidate_available {  | 
| 
84
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
4
 | 
   $available = undef;  | 
| 
85
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
86
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
87
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub available_APIs {  | 
| 
88
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
89
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #cache this crunch  | 
| 
90
 | 
100
 | 
  
100
  
 | 
 
 | 
  
100
  
 | 
  
1
  
 | 
282332
 | 
   return $available if $available;  | 
| 
91
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
92
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
   my ($self) = @_;  | 
| 
93
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
   my $d_all = $self->discover_all;  | 
| 
94
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
19
 | 
   croak 'no items in discovery data' unless defined $d_all->{items};  | 
| 
95
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
96
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #grab only entries with the four keys we want  | 
| 
97
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #and strip other keys  | 
| 
98
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
   my @keys = qw/name version documentationLink discoveryRestUrl/;  | 
| 
99
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
   my @relevant;  | 
| 
100
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
   for my $i (@{ $d_all->{items} }) {  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
    | 
| 
101
 | 
1003
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
1635
 | 
     next unless @keys == grep { exists $i->{$_} } @keys;  | 
| 
 
 | 
4012
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7443
 | 
    | 
| 
102
 | 
997
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1469
 | 
     push @relevant, { %{$i}{@keys} };  | 
| 
 
 | 
997
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3183
 | 
    | 
| 
103
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
104
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
105
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   my $reduced = reduce {  | 
| 
106
 | 
997
 | 
 
 | 
 
 | 
  
997
  
 | 
 
 | 
1549
 | 
     for my $key (qw/version documentationLink discoveryRestUrl/) {  | 
| 
107
 | 
2991
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
10675
 | 
       $a->{ $b->{name} }->{$key} //= [];  | 
| 
108
 | 
2991
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3997
 | 
       push @{ $a->{ $b->{name} }->{$key} }, $b->{$key};  | 
| 
 
 | 
2991
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7338
 | 
    | 
| 
109
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
110
 | 
997
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1429
 | 
     $a;  | 
| 
111
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
112
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
67
 | 
   {}, @relevant;  | 
| 
113
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
114
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #store it away globally  | 
| 
115
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1131
 | 
   $available = $reduced;  | 
| 
116
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
117
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
118
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub augment_discover_all_with_unlisted_experimental_api {  | 
| 
120
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
0
 | 
   my ($self, $api_spec) = @_;  | 
| 
121
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   carp <
 | 
| 
122
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This lengthy function name (augment_discover_all_with_unlisted_experimental_api)  | 
| 
123
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 will be removed soon.  Please use 'augment_with' instead.  | 
| 
124
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 DEPRECATION  | 
| 
125
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   $self->augment_with($api_spec);  | 
| 
126
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
127
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
128
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub augment_with {  | 
| 
129
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
  
1
  
 | 
155083
 | 
   my ($self, $api_spec) = @_;  | 
| 
130
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
131
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
   my $all = $self->discover_all();  | 
| 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
133
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   ## fail if any of the expected fields are not provided  | 
| 
134
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
   for my $field (  | 
| 
135
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     qw/version title description id kind documentationLink  | 
| 
136
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     discoveryRestUrl name/  | 
| 
137
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   ) {  | 
| 
138
 | 
8
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
18
 | 
     if (not defined $api_spec->{$field}) {  | 
| 
139
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       carp("required $field in provided api spec missing");  | 
| 
140
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
141
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
142
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
143
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
   push @{ $all->{items} }, $api_spec;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
    | 
| 
144
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
25
 | 
   $self->chi->set($self->discover_key, $all, '30d');  | 
| 
145
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1937
 | 
   $self->_invalidate_available;  | 
| 
146
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
300
 | 
   return $all;  | 
| 
147
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
148
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
149
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
150
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
151
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub service_exists {  | 
| 
152
 | 
43
 | 
 
 | 
 
 | 
  
43
  
 | 
  
1
  
 | 
3790
 | 
   my ($self, $api) = @_;  | 
| 
153
 | 
43
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
104
 | 
   return unless $api;  | 
| 
154
 | 
43
 | 
 
 | 
 
 | 
 
 | 
 
 | 
136
 | 
   return $self->available_APIs->{$api};  | 
| 
155
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
156
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
157
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
158
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub available_versions {  | 
| 
159
 | 
28
 | 
 
 | 
 
 | 
  
28
  
 | 
  
1
  
 | 
2555
 | 
   my ($self, $api) = @_;  | 
| 
160
 | 
28
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
70
 | 
   return [] unless $api;  | 
| 
161
 | 
28
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
63
 | 
   return $self->available_APIs->{$api}->{version} // [];  | 
| 
162
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
163
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
164
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
165
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub latest_stable_version {  | 
| 
166
 | 
23
 | 
 
 | 
 
 | 
  
23
  
 | 
  
1
  
 | 
1650
 | 
   my ($self, $api) = @_;  | 
| 
167
 | 
23
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
73
 | 
   return '' unless $api;  | 
| 
168
 | 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
73
 | 
   my $versions = $self->available_versions($api);  | 
| 
169
 | 
23
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
69
 | 
   return '' unless $versions;  | 
| 
170
 | 
23
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
48
 | 
   return '' unless @{$versions} > 0;  | 
| 
 
 | 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
81
 | 
    | 
| 
171
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
172
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #remove alpha or beta versions  | 
| 
173
 | 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
64
 | 
   my @stable = grep { !/beta|alpha/ } @$versions;  | 
| 
 
 | 
60
 | 
 
 | 
 
 | 
 
 | 
 
 | 
306
 | 
    | 
| 
174
 | 
23
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
129
 | 
   return $stable[-1] || '';  | 
| 
175
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
176
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
177
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
178
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub process_api_version {  | 
| 
179
 | 
28
 | 
 
 | 
 
 | 
  
28
  
 | 
  
1
  
 | 
13350
 | 
   my ($self, $params) = @_;  | 
| 
180
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
181
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # scalar parameter not hashref - so assume is intended to be $params->{api}  | 
| 
182
 | 
28
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
143
 | 
   $params = { api => $params } if ref $params eq '';  | 
| 
183
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
184
 | 
28
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
134
 | 
   croak "'api' must be defined" unless $params->{api};  | 
| 
185
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
186
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   ## trim any resource, method or version details in api id  | 
| 
187
 | 
28
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
132
 | 
   if ($params->{api} =~ /([^:]+):(v[^\.]+)/ixsm) {  | 
| 
188
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
     $params->{api}     = $1;  | 
| 
189
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
     $params->{version} = $2;  | 
| 
190
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
191
 | 
28
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
125
 | 
   if ($params->{api} =~ /^(.*?)\./xsm) {  | 
| 
192
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
43
 | 
     $params->{api} = $1;  | 
| 
193
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
194
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
195
 | 
28
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
95
 | 
   unless ($self->service_exists($params->{api})) {  | 
| 
196
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
308
 | 
     croak "$params->{api} does not seem to be a valid Google API";  | 
| 
197
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
198
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
199
 | 
26
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
147
 | 
   $params->{version} //= $self->latest_stable_version($params->{api});  | 
| 
200
 | 
26
 | 
 
 | 
 
 | 
 
 | 
 
 | 
83
 | 
   return $params;  | 
| 
201
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
202
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
203
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
204
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
205
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub get_api_discovery_for_api_id {  | 
| 
206
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
0
 | 
   carp <
 | 
| 
207
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This long method name (get_api_discovery_for_api_id) is being deprecated  | 
| 
208
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 in favor of get_api_document. Please switch your code soon  | 
| 
209
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 DEPRECATION  | 
| 
210
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   shift->get_api_document(@_);  | 
| 
211
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
212
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
213
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub get_api_document {  | 
| 
214
 | 
23
 | 
 
 | 
 
 | 
  
23
  
 | 
  
1
  
 | 
228
 | 
   my ($self, $arg) = @_;  | 
| 
215
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
216
 | 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
83
 | 
   my $params = $self->process_api_version($arg);  | 
| 
217
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
54
 | 
   my $apis   = $self->available_APIs();  | 
| 
218
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
219
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
64
 | 
   my $api = $apis->{ $params->{api} };  | 
| 
220
 | 
22
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
83
 | 
   croak "No versions found for $params->{api}" unless $api->{version};  | 
| 
221
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
222
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
51
 | 
   my @versions = @{ $api->{version} };  | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
106
 | 
    | 
| 
223
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
87
 | 
   my @urls     = @{ $api->{discoveryRestUrl} };  | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
90
 | 
    | 
| 
224
 | 
22
 | 
  
100
  
 | 
 
 | 
  
56
  
 | 
 
 | 
321
 | 
   my ($url) = pairwise { $a eq $params->{version} ? $b : () } @versions, @urls;  | 
| 
 
 | 
56
 | 
 
 | 
 
 | 
 
 | 
 
 | 
214
 | 
    | 
| 
225
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
226
 | 
22
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
124
 | 
   croak "Couldn't find correct url for $params->{api} $params->{version}"  | 
| 
227
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     unless $url;  | 
| 
228
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
229
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
91
 | 
   $self->get_with_cache($url);  | 
| 
230
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
231
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
232
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #TODO- HERE - we are here in refactoring  | 
| 
233
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _extract_resource_methods_from_api_spec {  | 
| 
234
 | 
144
 | 
 
 | 
 
 | 
  
144
  
 | 
 
 | 
325
 | 
   my ($self, $tree, $api_spec, $ret) = @_;  | 
| 
235
 | 
144
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
328
 | 
   $ret = {} unless defined $ret;  | 
| 
236
 | 
144
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
336
 | 
   croak("ret not a hash - $tree, $api_spec, $ret") unless ref($ret) eq 'HASH';  | 
| 
237
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
238
 | 
144
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
539
 | 
   if (defined $api_spec->{methods} && ref($api_spec->{methods}) eq 'HASH') {  | 
| 
239
 | 
108
 | 
 
 | 
 
 | 
 
 | 
 
 | 
207
 | 
     foreach my $method (keys %{ $api_spec->{methods} }) {  | 
| 
 
 | 
108
 | 
 
 | 
 
 | 
 
 | 
 
 | 
393
 | 
    | 
| 
240
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       $ret->{"$tree.$method"} = $api_spec->{methods}{$method}  | 
| 
241
 | 
494
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
2291
 | 
         if ref($api_spec->{methods}{$method}) eq 'HASH';  | 
| 
242
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
243
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
244
 | 
144
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
356
 | 
   if (defined $api_spec->{resources}) {  | 
| 
245
 | 
54
 | 
 
 | 
 
 | 
 
 | 
 
 | 
111
 | 
     foreach my $resource (keys %{ $api_spec->{resources} }) {  | 
| 
 
 | 
54
 | 
 
 | 
 
 | 
 
 | 
 
 | 
200
 | 
    | 
| 
246
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       ## NB - recursive traversal down tree of api_spec resources  | 
| 
247
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       $self->_extract_resource_methods_from_api_spec("$tree.$resource",  | 
| 
248
 | 
124
 | 
 
 | 
 
 | 
 
 | 
 
 | 
506
 | 
         $api_spec->{resources}{$resource}, $ret);  | 
| 
249
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
250
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
251
 | 
144
 | 
 
 | 
 
 | 
 
 | 
 
 | 
344
 | 
   return $ret;  | 
| 
252
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
253
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
254
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
255
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
256
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub extract_method_discovery_detail_from_api_spec {  | 
| 
257
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
0
 | 
   carp <
 | 
| 
258
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This rather long method name (extract_method_discovery_detail_from_api_spec)  | 
| 
259
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 is being deprecated in favor of get_method_details. Please switch soon  | 
| 
260
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 DEPRECATION  | 
| 
261
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   shift->get_method_details(@_);  | 
| 
262
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
263
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
264
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub get_method_details {  | 
| 
265
 | 
11
 | 
 
 | 
 
 | 
  
11
  
 | 
  
1
  
 | 
428
 | 
   my ($self, $tree, $api_version) = @_;  | 
| 
266
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   ## where tree is the method in format from _extract_resource_methods_from_api_spec() like projects.models.versions.get  | 
| 
267
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   ##   the root is the api id - further '.' sep levels represent resources until the tailing label that represents the method  | 
| 
268
 | 
11
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
46
 | 
   croak 'You must ask for a method!' unless defined $tree;  | 
| 
269
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
270
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
79
 | 
   my @nodes = split /\./smx, $tree;  | 
| 
271
 | 
11
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
49
 | 
   croak(  | 
| 
272
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 "tree structure '$tree' must contain at least 2 nodes including api id, [list of hierarchical resources ] and method - not "  | 
| 
273
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       . scalar(@nodes))  | 
| 
274
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     unless @nodes > 1;  | 
| 
275
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
276
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
37
 | 
   my $api_id = shift(@nodes);    ## api was head  | 
| 
277
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
31
 | 
   my $method = pop(@nodes);      ## method was tail  | 
| 
278
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
279
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   ## split out version if is defined as part of $tree  | 
| 
280
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   ## trim any resource, method or version details in api id  | 
| 
281
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   ## we have already isolated head from api tree children  | 
| 
282
 | 
11
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
58
 | 
   if ($api_id =~ /([^:]+):([^\.]+)$/ixsm) {  | 
| 
283
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
     $api_id      = $1;  | 
| 
284
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
     $api_version = $2;  | 
| 
285
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
286
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
287
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   ## handle incorrect api_id  | 
| 
288
 | 
11
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
46
 | 
   if ($self->service_exists($api_id) == 0) {  | 
| 
289
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     croak("unable to confirm that '$api_id' is a valid Google API service id");  | 
| 
290
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
291
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
292
 | 
11
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
45
 | 
   $api_version = $self->latest_stable_version($api_id) unless $api_version;  | 
| 
293
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
294
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
295
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   ## TODO: confirm that spec available for api version  | 
| 
296
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
65
 | 
   my $api_spec =  | 
| 
297
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $self->get_api_document({ api => $api_id, version => $api_version });  | 
| 
298
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
299
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
300
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   ## we use the schemas to substitute into '$ref' keyed placeholders  | 
| 
301
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
50
 | 
   my $schemas = {};  | 
| 
302
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
26
 | 
   foreach my $schema_key (sort keys %{ $api_spec->{schemas} }) {  | 
| 
 
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
630
 | 
    | 
| 
303
 | 
926
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2106
 | 
     $schemas->{$schema_key} = $api_spec->{'schemas'}{$schema_key};  | 
| 
304
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
305
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
306
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   ## recursive walk through the structure in _fix_ref  | 
| 
307
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   ##  substitute the schema keys into the total spec to include  | 
| 
308
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   ##  '$ref' values within the schema structures themselves  | 
| 
309
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   ##  including within the schema spec structures (NB assumes no cyclic structures )  | 
| 
310
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   ##   otherwise would could recursive chaos  | 
| 
311
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
87
 | 
   my $api_spec_fix = $self->_fix_ref($api_spec, $schemas)  | 
| 
312
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ;    ## first level ( '$ref' in the method params and return values etc )  | 
| 
313
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
41
 | 
   $api_spec = $self->_fix_ref($api_spec_fix, $schemas)  | 
| 
314
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ;    ## second level ( '$ref' in the interpolated schemas from first level )  | 
| 
315
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
316
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   ## now extract all the methods (recursive )  | 
| 
317
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2324
 | 
   my $all_api_methods =  | 
| 
318
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $self->_extract_resource_methods_from_api_spec("$api_id:$api_version",  | 
| 
319
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $api_spec);  | 
| 
320
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
321
 | 
11
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
65
 | 
   unless (defined $all_api_methods->{$tree}) {  | 
| 
322
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
30
 | 
     $all_api_methods =  | 
| 
323
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       $self->_extract_resource_methods_from_api_spec($api_id, $api_spec);  | 
| 
324
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
325
 | 
11
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
56
 | 
   if ($all_api_methods->{$tree}) {  | 
| 
326
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
327
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #add in the global parameters to the endpoint,  | 
| 
328
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #stored in the top level of the api_spec  | 
| 
329
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # TODO - why are we mutating the main hash?  | 
| 
330
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $all_api_methods->{$tree}{parameters} = {  | 
| 
331
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
64
 | 
       %{ $all_api_methods->{$tree}{parameters} },  | 
| 
332
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
32
 | 
       %{ $api_spec->{parameters} }  | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
204
 | 
    | 
| 
333
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     };  | 
| 
334
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21854
 | 
     return $all_api_methods->{$tree};  | 
| 
335
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
336
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
337
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   croak(  | 
| 
338
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
259
 | 
 "Unable to find method detail for '$tree' within Google Discovery Spec for $api_id version $api_version"  | 
| 
339
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   );  | 
| 
340
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
341
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ########################################################  | 
| 
342
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
343
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ########################################################  | 
| 
344
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ########################################################  | 
| 
345
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
346
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #=head2 C  | 
| 
347
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
348
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #This sub walks through the structure and replaces any hashes keyed with '$ref' with  | 
| 
349
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #the value defined in $schemas->{  }  | 
| 
350
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
351
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #eg  | 
| 
352
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # ->{'response'}{'$ref'}{'Buckets'}  | 
| 
353
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # is replaced with  | 
| 
354
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # ->{response}{ $schemas->{Buckets} }  | 
| 
355
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
356
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # It assumes that the schemas have been extracted from the original discover for the API  | 
| 
357
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # and is typically applied to the method ( api endpoint ) to provide a fully descriptive  | 
| 
358
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # structure without external references.  | 
| 
359
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
360
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #=cut  | 
| 
361
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
362
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ########################################################  | 
| 
363
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _fix_ref {  | 
| 
364
 | 
127726
 | 
 
 | 
 
 | 
  
127726
  
 | 
 
 | 
235163
 | 
   my ($self, $node, $schemas) = @_;  | 
| 
365
 | 
127726
 | 
 
 | 
 
 | 
 
 | 
 
 | 
185912
 | 
   my $ret = undef;  | 
| 
366
 | 
127726
 | 
 
 | 
 
 | 
 
 | 
 
 | 
199629
 | 
   my $r   = ref($node);  | 
| 
367
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
368
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
369
 | 
127726
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
252950
 | 
   if ($r eq 'ARRAY') {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
370
 | 
5209
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9086
 | 
     $ret = [];  | 
| 
371
 | 
5209
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9919
 | 
     foreach my $el (@$node) {  | 
| 
372
 | 
31317
 | 
 
 | 
 
 | 
 
 | 
 
 | 
57206
 | 
       push @$ret, $self->_fix_ref($el, $schemas);  | 
| 
373
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
374
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } elsif ($r eq 'HASH') {  | 
| 
375
 | 
31827
 | 
 
 | 
 
 | 
 
 | 
 
 | 
52420
 | 
     $ret = {};  | 
| 
376
 | 
31827
 | 
 
 | 
 
 | 
 
 | 
 
 | 
97049
 | 
     foreach my $key (keys %$node) {  | 
| 
377
 | 
101289
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
187296
 | 
       if ($key eq '$ref') {  | 
| 
378
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
379
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         #say $node->{'$ref'};  | 
| 
380
 | 
4902
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13663
 | 
         $ret = $schemas->{ $node->{'$ref'} };  | 
| 
381
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       } else {  | 
| 
382
 | 
96387
 | 
 
 | 
 
 | 
 
 | 
 
 | 
200076
 | 
         $ret->{$key} = $self->_fix_ref($node->{$key}, $schemas);  | 
| 
383
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
384
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
385
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } else {  | 
| 
386
 | 
90690
 | 
 
 | 
 
 | 
 
 | 
 
 | 
140537
 | 
     $ret = $node;  | 
| 
387
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
388
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
389
 | 
127726
 | 
 
 | 
 
 | 
 
 | 
 
 | 
336536
 | 
   return $ret;  | 
| 
390
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
391
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ########################################################  | 
| 
392
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
393
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
394
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
395
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #TODO: consider ? refactor to allow parameters either as a single api id such as 'gmail'  | 
| 
396
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #      as well as the currently accepted  hash keyed on the api and version  | 
| 
397
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
398
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #SEE ALSO:  | 
| 
399
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  The following methods are delegated through to Client::Discovery - see perldoc WebService::Client::Discovery for detils  | 
| 
400
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
401
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  get_method_meta  | 
| 
402
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  discover_all  | 
| 
403
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  extract_method_discovery_detail_from_api_spec  | 
| 
404
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  get_api_discovery_for_api_id  | 
| 
405
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
406
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ########################################################  | 
| 
407
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #TODO- give short name and deprecate  | 
| 
408
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub methods_available_for_google_api_id {  | 
| 
409
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
0
 | 
   my ($self, $api_id, $version) = @_;  | 
| 
410
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
411
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   $version = $self->latest_stable_version($api_id) unless $version;  | 
| 
412
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   ## TODO: confirm that spec available for api version  | 
| 
413
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my $api_spec = $self->get_api_discovery_for_api_id(  | 
| 
414
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     { api => $api_id, version => $version });  | 
| 
415
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my $methods =  | 
| 
416
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $self->_extract_resource_methods_from_api_spec($api_id, $api_spec);  | 
| 
417
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   return $methods;  | 
| 
418
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
419
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ########################################################  | 
| 
420
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
421
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
422
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
423
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub list_of_available_google_api_ids {  | 
| 
424
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
0
 | 
   carp <
 | 
| 
425
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This rather long function name (list_of_available_google_api_ids)  | 
| 
426
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 is being deprecated in favor of the shorter list_api_ids. Please  | 
| 
427
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 update your code accordingly.  | 
| 
428
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 DEPRECATION  | 
| 
429
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   shift->list_api_ids;  | 
| 
430
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
431
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ## returns a list of all available API Services  | 
| 
432
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub list_api_ids {  | 
| 
433
 | 
6
 | 
 
 | 
 
 | 
  
6
  
 | 
  
1
  
 | 
16714
 | 
   my ($self) = @_;  | 
| 
434
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
   my @api_list = keys %{ $self->available_APIs };  | 
| 
 
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
    | 
| 
435
 | 
6
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
328
 | 
   return wantarray ? @api_list : join(',', @api_list);  | 
| 
436
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
437
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
438
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
439
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 1;  | 
| 
440
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
441
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 __END__  |