line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package WWW::Ohloh::API; |
2
|
|
|
|
|
|
|
|
3
|
15
|
|
|
15
|
|
3093948
|
use warnings; |
|
15
|
|
|
|
|
35
|
|
|
15
|
|
|
|
|
1199
|
|
4
|
15
|
|
|
15
|
|
80
|
use strict; |
|
15
|
|
|
|
|
27
|
|
|
15
|
|
|
|
|
470
|
|
5
|
15
|
|
|
15
|
|
67
|
use Carp; |
|
15
|
|
|
|
|
35
|
|
|
15
|
|
|
|
|
1221
|
|
6
|
|
|
|
|
|
|
|
7
|
15
|
|
|
15
|
|
8701
|
use Object::InsideOut; |
|
15
|
|
|
|
|
837063
|
|
|
15
|
|
|
|
|
84
|
|
8
|
|
|
|
|
|
|
|
9
|
15
|
|
|
15
|
|
1617193
|
use LWP::UserAgent; |
|
15
|
|
|
|
|
6394581
|
|
|
15
|
|
|
|
|
563
|
|
10
|
15
|
|
|
15
|
|
14232
|
use Readonly; |
|
15
|
|
|
|
|
46273
|
|
|
15
|
|
|
|
|
968
|
|
11
|
15
|
|
|
15
|
|
10649
|
use XML::LibXML; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
use Params::Validate qw(:all); |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
use WWW::Ohloh::API::Account; |
15
|
|
|
|
|
|
|
use WWW::Ohloh::API::Analysis; |
16
|
|
|
|
|
|
|
use WWW::Ohloh::API::Project; |
17
|
|
|
|
|
|
|
use WWW::Ohloh::API::Projects; |
18
|
|
|
|
|
|
|
use WWW::Ohloh::API::Languages; |
19
|
|
|
|
|
|
|
use WWW::Ohloh::API::ActivityFact; |
20
|
|
|
|
|
|
|
use WWW::Ohloh::API::ActivityFacts; |
21
|
|
|
|
|
|
|
use WWW::Ohloh::API::Kudos; |
22
|
|
|
|
|
|
|
use WWW::Ohloh::API::ContributorLanguageFact; |
23
|
|
|
|
|
|
|
use WWW::Ohloh::API::Enlistments; |
24
|
|
|
|
|
|
|
use WWW::Ohloh::API::Factoid; |
25
|
|
|
|
|
|
|
use WWW::Ohloh::API::SizeFact; |
26
|
|
|
|
|
|
|
use WWW::Ohloh::API::Stack; |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
use Digest::MD5 qw/ md5_hex /; |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
our $VERSION = '0.3.2'; |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
Readonly our $OHLOH_URL => 'http://www.ohloh.net/'; |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
our $useragent_signature = "WWW-Ohloh-API/$VERSION"; |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
my @api_key_of : Field : Std(api_key) : Arg(api_key); |
37
|
|
|
|
|
|
|
my @api_version_of : Field : Default(1); # for now, there's only v1 |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
my @user_agent_of : Field; |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
my @debugging : Field : Arg(debug) : Default(0) : Std(debug); |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
my @parser_of : Field; |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
sub fetch_messages { |
48
|
|
|
|
|
|
|
my $self = shift; |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
require WWW::Ohloh::API::Messages; |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
return WWW::Ohloh::API::Messages->new( ohloh => $self, @_ ); |
53
|
|
|
|
|
|
|
} |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
sub get_account_stack { |
58
|
|
|
|
|
|
|
my $self = shift; |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
my $id = shift; |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
$id = md5_hex($id) if -1 < index $id, '@'; # it's an email |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
my ( $url, $xml ) = |
65
|
|
|
|
|
|
|
$self->_query_server("accounts/$id/stacks/default.xml"); |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
return WWW::Ohloh::API::Stack->new( |
68
|
|
|
|
|
|
|
ohloh => $self, |
69
|
|
|
|
|
|
|
request_url => $url, |
70
|
|
|
|
|
|
|
xml => $xml->findnodes('stack[1]'), |
71
|
|
|
|
|
|
|
); |
72
|
|
|
|
|
|
|
} |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
sub get_project_stacks { |
77
|
|
|
|
|
|
|
my $self = shift; |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
my $project = shift; |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
my ( $url, $xml ) = $self->_query_server("projects/$project/stacks.xml"); |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
return map { |
84
|
|
|
|
|
|
|
WWW::Ohloh::API::Stack->new( |
85
|
|
|
|
|
|
|
ohloh => $self, |
86
|
|
|
|
|
|
|
request_url => $url, |
87
|
|
|
|
|
|
|
xml => $_, |
88
|
|
|
|
|
|
|
) |
89
|
|
|
|
|
|
|
} $xml->findnodes('//result/stack'); |
90
|
|
|
|
|
|
|
} |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
sub get_size_facts { |
95
|
|
|
|
|
|
|
my $self = shift; |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
my ( $project_id, $analysis_id ) = |
98
|
|
|
|
|
|
|
validate_pos( @_, 1, { default => 'latest' }, ); |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
my ( $url, $xml ) = $self->_query_server( |
101
|
|
|
|
|
|
|
"projects/$project_id/analyses/$analysis_id/size_facts.xml"); |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
return map { |
104
|
|
|
|
|
|
|
WWW::Ohloh::API::SizeFact->new( |
105
|
|
|
|
|
|
|
ohloh => $self, |
106
|
|
|
|
|
|
|
request_url => $url, |
107
|
|
|
|
|
|
|
xml => $_ |
108
|
|
|
|
|
|
|
) |
109
|
|
|
|
|
|
|
} $xml->findnodes('//size_fact'); |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
} |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
sub get_account { |
116
|
|
|
|
|
|
|
my $self = shift; |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
my ( $type, $id ) = @_; |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
$type eq 'id' |
121
|
|
|
|
|
|
|
or $type eq 'email' |
122
|
|
|
|
|
|
|
or croak "first argument must be 'id' or 'email'"; |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
$id = md5_hex($id) if $type eq 'email'; |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
my ( $url, $xml ) = $self->_query_server("accounts/$id.xml"); |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
return WWW::Ohloh::API::Account->new( |
129
|
|
|
|
|
|
|
ohloh => $self, |
130
|
|
|
|
|
|
|
request_url => $url, |
131
|
|
|
|
|
|
|
xml => $xml->findnodes('account[1]'), |
132
|
|
|
|
|
|
|
); |
133
|
|
|
|
|
|
|
} |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
sub get_enlistments { |
138
|
|
|
|
|
|
|
my $self = shift; |
139
|
|
|
|
|
|
|
my %arg = @_; |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
return WWW::Ohloh::API::Enlistments->new( |
142
|
|
|
|
|
|
|
ohloh => $self, |
143
|
|
|
|
|
|
|
project_id => $arg{project_id}, |
144
|
|
|
|
|
|
|
( sort => $arg{sort} ) x !!$arg{sort}, |
145
|
|
|
|
|
|
|
); |
146
|
|
|
|
|
|
|
} |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
sub get_factoids { |
151
|
|
|
|
|
|
|
my $self = shift; |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
my $project_id = shift; |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
my ( $url, $xml ) = |
156
|
|
|
|
|
|
|
$self->_query_server("projects/$project_id/factoids.xml"); |
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
return map { |
159
|
|
|
|
|
|
|
WWW::Ohloh::API::Factoid->new( |
160
|
|
|
|
|
|
|
ohloh => $self, |
161
|
|
|
|
|
|
|
request_url => $url, |
162
|
|
|
|
|
|
|
xml => $_ |
163
|
|
|
|
|
|
|
) |
164
|
|
|
|
|
|
|
} $xml->findnodes('//factoid'); |
165
|
|
|
|
|
|
|
} |
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
sub get_contributor_language_facts { |
170
|
|
|
|
|
|
|
my $self = shift; |
171
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
my %param = validate( |
173
|
|
|
|
|
|
|
@_, |
174
|
|
|
|
|
|
|
{ project_id => 1, |
175
|
|
|
|
|
|
|
contributor_id => 1, |
176
|
|
|
|
|
|
|
} ); |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
my ( $url, $xml ) = $self->_query_server( |
179
|
|
|
|
|
|
|
"projects/$param{project_id}/contributors/$param{contributor_id}.xml" |
180
|
|
|
|
|
|
|
); |
181
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
return map { |
183
|
|
|
|
|
|
|
WWW::Ohloh::API::ContributorLanguageFact->new( |
184
|
|
|
|
|
|
|
ohloh => $self, |
185
|
|
|
|
|
|
|
request_url => $url, |
186
|
|
|
|
|
|
|
xml => $_ |
187
|
|
|
|
|
|
|
) |
188
|
|
|
|
|
|
|
} $xml->findnodes('//contributor_language_fact'); |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
} |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
sub get_kudos { |
195
|
|
|
|
|
|
|
my $self = shift; |
196
|
|
|
|
|
|
|
my ( $type, $id ) = @_; |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
$type eq 'id' |
199
|
|
|
|
|
|
|
or $type eq 'email' |
200
|
|
|
|
|
|
|
or croak "first argument must be 'id' or 'email'"; |
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
$id = md5_hex($id) if $type eq 'email'; |
203
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
return WWW::Ohloh::API::Kudos->new( |
205
|
|
|
|
|
|
|
ohloh => $self, |
206
|
|
|
|
|
|
|
id => $id, |
207
|
|
|
|
|
|
|
); |
208
|
|
|
|
|
|
|
} |
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
sub get_project { |
213
|
|
|
|
|
|
|
my $self = shift; |
214
|
|
|
|
|
|
|
my $id = shift; |
215
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
my ( $url, $xml ) = $self->_query_server("projects/$id.xml"); |
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
return WWW::Ohloh::API::Project->new( |
219
|
|
|
|
|
|
|
ohloh => $self, |
220
|
|
|
|
|
|
|
request_url => $url, |
221
|
|
|
|
|
|
|
xml => $xml->findnodes('project[1]'), |
222
|
|
|
|
|
|
|
); |
223
|
|
|
|
|
|
|
} |
224
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
sub get_projects { |
228
|
|
|
|
|
|
|
my $self = shift; |
229
|
|
|
|
|
|
|
my %arg = validate( @_, { query => 0, sort => 0, max => 0 } ); |
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
return WWW::Ohloh::API::Projects->new( |
232
|
|
|
|
|
|
|
ohloh => $self, |
233
|
|
|
|
|
|
|
query => $arg{query}, |
234
|
|
|
|
|
|
|
sort => $arg{sort}, |
235
|
|
|
|
|
|
|
max => $arg{max}, |
236
|
|
|
|
|
|
|
); |
237
|
|
|
|
|
|
|
} |
238
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
240
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
sub get_analysis { |
242
|
|
|
|
|
|
|
my $self = shift; |
243
|
|
|
|
|
|
|
my $project = shift; |
244
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
$_[0] ||= 'latest'; |
246
|
|
|
|
|
|
|
|
247
|
|
|
|
|
|
|
my ( $url, $xml ) = |
248
|
|
|
|
|
|
|
$self->_query_server("projects/$project/analyses/$_[0].xml"); |
249
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
my $analysis = WWW::Ohloh::API::Analysis->new( |
251
|
|
|
|
|
|
|
request_url => $url, |
252
|
|
|
|
|
|
|
xml => $xml->findnodes('analysis[1]'), |
253
|
|
|
|
|
|
|
); |
254
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
unless ( $analysis->project_id == $project ) { |
256
|
|
|
|
|
|
|
croak "analysis $_[0] doesn't apply to project $project"; |
257
|
|
|
|
|
|
|
} |
258
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
return $analysis; |
260
|
|
|
|
|
|
|
} |
261
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
sub get_languages { |
265
|
|
|
|
|
|
|
my $self = shift; |
266
|
|
|
|
|
|
|
my %arg = @_; |
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
return WWW::Ohloh::API::Languages->new( |
269
|
|
|
|
|
|
|
ohloh => $self, |
270
|
|
|
|
|
|
|
( sort => $arg{sort} ) x !!$arg{sort}, |
271
|
|
|
|
|
|
|
); |
272
|
|
|
|
|
|
|
} |
273
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
sub get_language { |
277
|
|
|
|
|
|
|
my $self = shift; |
278
|
|
|
|
|
|
|
my $id = shift; |
279
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
my ( $url, $xml ) = $self->_query_server("languages/$id.xml"); |
281
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
return WWW::Ohloh::API::Language->new( |
283
|
|
|
|
|
|
|
request_url => $url, |
284
|
|
|
|
|
|
|
xml => $xml->findnodes('language[1]'), |
285
|
|
|
|
|
|
|
); |
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
} |
288
|
|
|
|
|
|
|
|
289
|
|
|
|
|
|
|
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
290
|
|
|
|
|
|
|
|
291
|
|
|
|
|
|
|
sub get_activity_facts { |
292
|
|
|
|
|
|
|
my $self = shift; |
293
|
|
|
|
|
|
|
my ( $project, $analysis ) = |
294
|
|
|
|
|
|
|
validate_pos( @_, 1, { default => 'latest' }, ); |
295
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
return WWW::Ohloh::API::ActivityFacts->new( |
297
|
|
|
|
|
|
|
ohloh => $self, |
298
|
|
|
|
|
|
|
project => $project, |
299
|
|
|
|
|
|
|
analysis => $analysis, |
300
|
|
|
|
|
|
|
); |
301
|
|
|
|
|
|
|
} |
302
|
|
|
|
|
|
|
|
303
|
|
|
|
|
|
|
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
sub _ua { |
306
|
|
|
|
|
|
|
my $self = shift; |
307
|
|
|
|
|
|
|
my $ua; |
308
|
|
|
|
|
|
|
unless ( $ua = $user_agent_of[$$self] ) { |
309
|
|
|
|
|
|
|
$ua = $user_agent_of[$$self] = LWP::UserAgent->new; |
310
|
|
|
|
|
|
|
$ua->agent($useragent_signature); |
311
|
|
|
|
|
|
|
} |
312
|
|
|
|
|
|
|
return $ua; |
313
|
|
|
|
|
|
|
} |
314
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
sub _parser { |
316
|
|
|
|
|
|
|
my $self = shift; |
317
|
|
|
|
|
|
|
return $parser_of[$$self] ||= XML::LibXML->new; |
318
|
|
|
|
|
|
|
} |
319
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
sub _query_server { |
321
|
|
|
|
|
|
|
my $self = shift; |
322
|
|
|
|
|
|
|
my $url = shift; |
323
|
|
|
|
|
|
|
my %param = $_[0] ? %{ $_[0] } : (); |
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
$param{api_key} = $self->get_api_key |
326
|
|
|
|
|
|
|
or croak "api key not configured"; |
327
|
|
|
|
|
|
|
|
328
|
|
|
|
|
|
|
$param{v} = $api_version_of[$$self]; |
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
$url = $OHLOH_URL . $url; |
331
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
$url .= '?' . join '&', map { "$_=$param{$_}" } keys %param; |
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
warn "querying ohloh server with $url" if $debugging[$$self]; |
335
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
# TODO: beef up here for failures |
337
|
|
|
|
|
|
|
my $request = HTTP::Request->new( GET => $url ); |
338
|
|
|
|
|
|
|
my $response = $self->_ua->request($request); |
339
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
unless ( $response->is_success ) { |
341
|
|
|
|
|
|
|
croak "http query to Ohloh server failed: " . $response->status_line; |
342
|
|
|
|
|
|
|
} |
343
|
|
|
|
|
|
|
|
344
|
|
|
|
|
|
|
my $result = $response->content; |
345
|
|
|
|
|
|
|
|
346
|
|
|
|
|
|
|
my $dom = eval { $self->_parser->parse_string($result) } |
347
|
|
|
|
|
|
|
or croak "server didn't feed back valid xml: $@"; |
348
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
if ( $dom->findvalue('/response/status/text()') ne 'success' ) { |
350
|
|
|
|
|
|
|
croak "query to Ohloh server failed: ", |
351
|
|
|
|
|
|
|
$dom->findvalue('/response/status/text()'); |
352
|
|
|
|
|
|
|
} |
353
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
return $url, $dom->findnodes('/response/result[1]'); |
355
|
|
|
|
|
|
|
} |
356
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
1; # Magic true value required at end of module |
358
|
|
|
|
|
|
|
__END__ |
359
|
|
|
|
|
|
|
|
360
|
|
|
|
|
|
|
=head1 NAME |
361
|
|
|
|
|
|
|
|
362
|
|
|
|
|
|
|
WWW::Ohloh::API - Ohloh API implementation |
363
|
|
|
|
|
|
|
|
364
|
|
|
|
|
|
|
=head1 SYNOPSIS |
365
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
use WWW::Ohloh::API; |
367
|
|
|
|
|
|
|
|
368
|
|
|
|
|
|
|
my $ohloh = WWW::Ohloh::API->new( api_key => $my_api_key ); |
369
|
|
|
|
|
|
|
my $account $ohloh->get_account( id => 12933 ); |
370
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
print $account->name; |
372
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
=head1 DESCRIPTION |
374
|
|
|
|
|
|
|
|
375
|
|
|
|
|
|
|
This module is a Perl interface to the Ohloh API as defined at |
376
|
|
|
|
|
|
|
http://www.ohloh.net/api/getting_started. |
377
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
=head1 METHODS |
379
|
|
|
|
|
|
|
|
380
|
|
|
|
|
|
|
=head2 new( [ api_key => $api_key ] ) |
381
|
|
|
|
|
|
|
|
382
|
|
|
|
|
|
|
Create a new WWW::Ohloh::API object. To be able to retrieve information |
383
|
|
|
|
|
|
|
from the Ohloh server, an api key must be either passed to the constructor |
384
|
|
|
|
|
|
|
or set via the L<set_api_key> method. |
385
|
|
|
|
|
|
|
|
386
|
|
|
|
|
|
|
my $ohloh = WWW::Ohloh::API->new( api_key => $your_key ); |
387
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
=head2 get_account( [ id | email ] => $account_id ) |
389
|
|
|
|
|
|
|
|
390
|
|
|
|
|
|
|
Return the account associated with the $account_id as a |
391
|
|
|
|
|
|
|
L<WWW::Ohloh::API::Account> |
392
|
|
|
|
|
|
|
object. If no such account exists, an error is thrown. |
393
|
|
|
|
|
|
|
The $accound_id can either be specified as the Ohloh id number, |
394
|
|
|
|
|
|
|
or the email address associated with the account. |
395
|
|
|
|
|
|
|
|
396
|
|
|
|
|
|
|
my $account = $ohloh->get_account( id => 12933 ); |
397
|
|
|
|
|
|
|
my $other_accound = $ohloh->get_account( email => 'foo@bar.com' ); |
398
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
|
400
|
|
|
|
|
|
|
=head2 get_project( $id ) |
401
|
|
|
|
|
|
|
|
402
|
|
|
|
|
|
|
Return the project having the Ohloh id I<$id> as a |
403
|
|
|
|
|
|
|
L<WWW::Ohloh::API::Project>. If no such project exists, |
404
|
|
|
|
|
|
|
an error is thrown. |
405
|
|
|
|
|
|
|
|
406
|
|
|
|
|
|
|
my $project = $ohloh->get_project( 1234) ; |
407
|
|
|
|
|
|
|
print $project->name; |
408
|
|
|
|
|
|
|
|
409
|
|
|
|
|
|
|
=head2 get_projects( query => $query, sort => $sorting_order, max => $nbr ) |
410
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
Return a set of projects as a L<WWW::Ohloh::API::Projects> object. |
412
|
|
|
|
|
|
|
|
413
|
|
|
|
|
|
|
=head3 Parameters |
414
|
|
|
|
|
|
|
|
415
|
|
|
|
|
|
|
=over |
416
|
|
|
|
|
|
|
|
417
|
|
|
|
|
|
|
=item query |
418
|
|
|
|
|
|
|
|
419
|
|
|
|
|
|
|
If provided, only the projects matching the query string are returned. |
420
|
|
|
|
|
|
|
A project matches the query string is any of its name, description |
421
|
|
|
|
|
|
|
or tags does. |
422
|
|
|
|
|
|
|
|
423
|
|
|
|
|
|
|
=item sort |
424
|
|
|
|
|
|
|
|
425
|
|
|
|
|
|
|
If provided, the projects will be returned according to the specified |
426
|
|
|
|
|
|
|
sorting order. Valid values are |
427
|
|
|
|
|
|
|
'created_at', 'description', 'id', 'name', 'stack_count', |
428
|
|
|
|
|
|
|
'updated_at', 'created_at_reverse', |
429
|
|
|
|
|
|
|
'description_reverse', 'id_reverse', 'name_reverse', |
430
|
|
|
|
|
|
|
'stack_count_reverse' or 'updated_at_reverse'. If no sorting order |
431
|
|
|
|
|
|
|
is explicitly given, 'id' is the default. |
432
|
|
|
|
|
|
|
|
433
|
|
|
|
|
|
|
=item max |
434
|
|
|
|
|
|
|
|
435
|
|
|
|
|
|
|
If given, the project set will returns at most I<$nbr> projects. |
436
|
|
|
|
|
|
|
|
437
|
|
|
|
|
|
|
# get top ten stacked projects |
438
|
|
|
|
|
|
|
my @top = $ohloh->get_projects( max => 10, sort => 'stack_count' )->all; |
439
|
|
|
|
|
|
|
|
440
|
|
|
|
|
|
|
=back |
441
|
|
|
|
|
|
|
|
442
|
|
|
|
|
|
|
=head2 get_languages( sort => $order ) |
443
|
|
|
|
|
|
|
|
444
|
|
|
|
|
|
|
Return the languages known to Ohloh a set of L<WWW::Ohloh::API::Language> |
445
|
|
|
|
|
|
|
objects. |
446
|
|
|
|
|
|
|
|
447
|
|
|
|
|
|
|
An optional I<sort> parameter can be passed to the method. The valid |
448
|
|
|
|
|
|
|
I<$order>s it accepts are |
449
|
|
|
|
|
|
|
C<total>, C<code>, C<projects>, C<comment_ratio>, |
450
|
|
|
|
|
|
|
C<contributors>, C<commits> and C<name>. If I<sort> is not explicitly called, |
451
|
|
|
|
|
|
|
projects are returned in alphabetical order of C<name>s. |
452
|
|
|
|
|
|
|
|
453
|
|
|
|
|
|
|
=head2 get_activity_facts( $project_id, $analysis ) |
454
|
|
|
|
|
|
|
|
455
|
|
|
|
|
|
|
Return a set of activity facts computed out of the project associated |
456
|
|
|
|
|
|
|
with the I<$project_id> as a L<WWW::Ohloh::API::ActivityFacts> object. |
457
|
|
|
|
|
|
|
|
458
|
|
|
|
|
|
|
The optional argument I<$analysis> can be either an Ohloh analysis id |
459
|
|
|
|
|
|
|
(which must be an analysis associated to the project) or the keyword |
460
|
|
|
|
|
|
|
'latest'. By default the latest analysis will be queried. |
461
|
|
|
|
|
|
|
|
462
|
|
|
|
|
|
|
=head2 get_contributor_language_facts( project_id => $p_id, contributor_id => $c_id ) |
463
|
|
|
|
|
|
|
|
464
|
|
|
|
|
|
|
my @facts = $ohloh->get_contributor_language_facts( |
465
|
|
|
|
|
|
|
project_id => 1234, |
466
|
|
|
|
|
|
|
contributor_id => 5678 |
467
|
|
|
|
|
|
|
); |
468
|
|
|
|
|
|
|
|
469
|
|
|
|
|
|
|
Return the list of contributor language facts associated to the |
470
|
|
|
|
|
|
|
contributor I<$c_id> for the project I<$p_id>. |
471
|
|
|
|
|
|
|
|
472
|
|
|
|
|
|
|
=head2 get_enlistments( project_id => $id ) |
473
|
|
|
|
|
|
|
|
474
|
|
|
|
|
|
|
Returns the list of enlistements pertaining to the |
475
|
|
|
|
|
|
|
given project as an L<WWW::Ohloh::API::Enlistment> object. |
476
|
|
|
|
|
|
|
|
477
|
|
|
|
|
|
|
my $enlistments = $ohloh->get_enlistments( project_id => 1234 ); |
478
|
|
|
|
|
|
|
|
479
|
|
|
|
|
|
|
while ( my $enlistment = $enlistments->next ) { |
480
|
|
|
|
|
|
|
# do stuff with $enlistment... |
481
|
|
|
|
|
|
|
} |
482
|
|
|
|
|
|
|
|
483
|
|
|
|
|
|
|
=head2 get_size_facts( $project_id, $analysis_id ) |
484
|
|
|
|
|
|
|
|
485
|
|
|
|
|
|
|
Return the list of L<WWW::Ohloh::API::SizeFact> objects pertaining to the |
486
|
|
|
|
|
|
|
given project and analysis. If I<$analysis_id> is not provided, it defaults |
487
|
|
|
|
|
|
|
to the latest analysis done on the project. |
488
|
|
|
|
|
|
|
|
489
|
|
|
|
|
|
|
=head2 get_project_stacks( $project_id ) |
490
|
|
|
|
|
|
|
|
491
|
|
|
|
|
|
|
Return the list of stacks containing the project as |
492
|
|
|
|
|
|
|
L<WWW::Ohloh::API::Stack> |
493
|
|
|
|
|
|
|
objects. |
494
|
|
|
|
|
|
|
|
495
|
|
|
|
|
|
|
=head2 get_account_stack( $account_id ) |
496
|
|
|
|
|
|
|
|
497
|
|
|
|
|
|
|
Return the stack associated with the account as an |
498
|
|
|
|
|
|
|
L<WWW::Ohloh::API::Stack> object. |
499
|
|
|
|
|
|
|
|
500
|
|
|
|
|
|
|
=head2 fetch_messages( [ account | project ] => I<$id> ) |
501
|
|
|
|
|
|
|
|
502
|
|
|
|
|
|
|
Returns the messages associated to the given account or project |
503
|
|
|
|
|
|
|
as a L<WWW::Ohloh::API::Messages> object. |
504
|
|
|
|
|
|
|
|
505
|
|
|
|
|
|
|
=head1 SEE ALSO |
506
|
|
|
|
|
|
|
|
507
|
|
|
|
|
|
|
=over |
508
|
|
|
|
|
|
|
|
509
|
|
|
|
|
|
|
=item * |
510
|
|
|
|
|
|
|
|
511
|
|
|
|
|
|
|
L<WWW::Ohloh::API::Project>, |
512
|
|
|
|
|
|
|
L<WWW::Ohloh::API::Projects>, |
513
|
|
|
|
|
|
|
L<WWW::Ohloh::API::Account>, |
514
|
|
|
|
|
|
|
L<WWW::Ohloh::API::KudoScore>, |
515
|
|
|
|
|
|
|
L<WWW::Ohloh::API::Languages>, |
516
|
|
|
|
|
|
|
L<WWW::Ohloh::API::Language>. |
517
|
|
|
|
|
|
|
|
518
|
|
|
|
|
|
|
=item * |
519
|
|
|
|
|
|
|
|
520
|
|
|
|
|
|
|
Ohloh API reference: http://www.ohloh.net/api/getting_started |
521
|
|
|
|
|
|
|
|
522
|
|
|
|
|
|
|
=item * |
523
|
|
|
|
|
|
|
|
524
|
|
|
|
|
|
|
How to obtain an Ohloh API key: http://www.ohloh.net/api_keys/new |
525
|
|
|
|
|
|
|
|
526
|
|
|
|
|
|
|
=back |
527
|
|
|
|
|
|
|
|
528
|
|
|
|
|
|
|
=head1 VERSION |
529
|
|
|
|
|
|
|
|
530
|
|
|
|
|
|
|
This document describes WWW::Ohloh::API version 0.3.2 |
531
|
|
|
|
|
|
|
|
532
|
|
|
|
|
|
|
=head1 BUGS AND LIMITATIONS |
533
|
|
|
|
|
|
|
|
534
|
|
|
|
|
|
|
WWW::Ohloh::API is very extremely alpha quality. It'll improve, |
535
|
|
|
|
|
|
|
but till then: I<Caveat emptor>. |
536
|
|
|
|
|
|
|
|
537
|
|
|
|
|
|
|
Please report any bugs or feature requests to |
538
|
|
|
|
|
|
|
C<bug-www-ohloh-api@rt.cpan.org>, or through the web interface at |
539
|
|
|
|
|
|
|
L<http://rt.cpan.org>. |
540
|
|
|
|
|
|
|
|
541
|
|
|
|
|
|
|
|
542
|
|
|
|
|
|
|
=head1 AUTHOR |
543
|
|
|
|
|
|
|
|
544
|
|
|
|
|
|
|
Yanick Champoux C<< <yanick@cpan.org> >> |
545
|
|
|
|
|
|
|
|
546
|
|
|
|
|
|
|
=head1 LICENCE AND COPYRIGHT |
547
|
|
|
|
|
|
|
|
548
|
|
|
|
|
|
|
Copyright (c) 2008, Yanick Champoux C<< <yanick@cpan.org> >>. All rights reserved. |
549
|
|
|
|
|
|
|
|
550
|
|
|
|
|
|
|
This module is free software; you can redistribute it and/or |
551
|
|
|
|
|
|
|
modify it under the same terms as Perl itself. See L<perlartistic>. |
552
|
|
|
|
|
|
|
|