File Coverage

blib/lib/Bot/Cobalt/Plugin/Extras/CPAN.pm
Criterion Covered Total %
statement 22 158 13.9
branch 0 60 0.0
condition 0 19 0.0
subroutine 8 16 50.0
pod 0 6 0.0
total 30 259 11.5


line stmt bran cond sub pod time code
1             package Bot::Cobalt::Plugin::Extras::CPAN;
2             $Bot::Cobalt::Plugin::Extras::CPAN::VERSION = '0.021003';
3 1     1   1220 use strictures 2;
  1         8  
  1         45  
4              
5 1     1   197 use Bot::Cobalt;
  1         2  
  1         7  
6 1     1   665 use Bot::Cobalt::Common;
  1         1  
  1         8  
7              
8 1     1   5 use Bot::Cobalt::Serializer;
  1         1  
  1         40  
9             our $Serializer = Bot::Cobalt::Serializer->new('JSON');
10              
11 1     1   466 use HTTP::Request;
  1         709  
  1         21  
12              
13 1     1   2100 use Module::CoreList;
  1         31043  
  1         10  
14              
15 1     1   458 use Try::Tiny;
  1         2  
  1         1519  
16              
17             our $HelpText
18             = 'try: dist, latest, tests, abstract, changes, belongs, license';
19              
20             ## FIXME cachedb?
21              
22 1     1 0 349 sub new { bless [], shift }
23              
24             sub Cobalt_register {
25 0     0 0   my ($self, $core) = splice @_, 0, 2;
26              
27 0           register $self, SERVER => qw/
28             public_cmd_cpan
29             public_cmd_corelist
30             mcpan_plug_resp_recv
31             /;
32              
33 0           logger->info("Loaded: !cpan");
34              
35 0           PLUGIN_EAT_NONE
36             }
37              
38             sub Cobalt_unregister {
39 0     0 0   my ($self, $core) = splice @_, 0, 2;
40 0           logger->info("Bye!");
41 0           PLUGIN_EAT_NONE
42             }
43              
44             sub Bot_public_cmd_corelist {
45 0     0 0   my ($self, $core) = splice @_, 0, 2;
46 0           my $msg = ${ $_[0] };
  0            
47              
48 0           my $dist = $msg->message_array->[0];
49              
50 0 0         unless ($dist) {
51 0           broadcast( 'message',
52             $msg->context, $msg->channel,
53             "corelist needs a module name."
54             );
55 0           return PLUGIN_EAT_ALL
56             }
57              
58 0           my $resp;
59 0           my $vers = $msg->message_array->[1];
60 0 0         if (my $first = Module::CoreList->first_release($dist, $vers)) {
61 0 0         $resp = $vers ?
62             "$dist ($vers) was released with $first"
63             : "$dist was released with $first"
64             } else {
65 0           $resp = "Module not found in core."
66             }
67              
68 0           broadcast( 'message',
69             $msg->context, $msg->channel,
70             join(', ', $msg->src_nick, $resp)
71             );
72             }
73              
74             sub Bot_public_cmd_cpan {
75 0     0 0   my ($self, $core) = splice @_, 0, 2;
76 0           my $msg = ${ $_[0] };
  0            
77              
78 0           my ($cmd, $dist) = @{ $msg->message_array };
  0            
79              
80 0 0         unless ($cmd) {
81 0           broadcast( 'message',
82             $msg->context, $msg->channel,
83             "No command; $HelpText"
84             );
85 0           return PLUGIN_EAT_ALL
86             }
87              
88 0 0         unless ($dist) {
89             # assume 'abstract' if only one arg
90 0           $dist = $cmd;
91 0           $cmd = 'abstract';
92             }
93              
94 0           $cmd = lc $cmd;
95 0 0 0       $dist =~ s/::/-/g
96             unless $cmd eq "belongs"
97             or $cmd eq "changes";
98 0           my $url = "/release/$dist";
99              
100 0           my $hints = +{
101             Context => $msg->context,
102             Channel => $msg->channel,
103             Nick => $msg->src_nick,
104             Dist => $dist,
105             Link => "http://www.metacpan.org${url}",
106             };
107              
108             CMD: {
109 0 0 0       if ($cmd eq 'latest' || $cmd eq 'release') {
  0            
110 0           $hints->{Type} = 'latest';
111             last CMD
112 0           }
113              
114 0 0         if ($cmd eq 'dist') {
115 0           $hints->{Type} = 'dist';
116             last CMD
117 0           }
118              
119 0 0 0       if ($cmd eq 'test' || $cmd eq 'tests') {
120 0           $hints->{Type} = 'tests';
121             last CMD
122 0           }
123              
124 0 0 0       if ($cmd eq 'info' || $cmd eq 'abstract') {
125 0           $hints->{Type} = 'abstract';
126             last CMD
127 0           }
128              
129 0 0         if ($cmd eq 'license') {
130 0           $hints->{Type} = 'license';
131             last CMD
132 0           }
133              
134 0 0         if ($cmd eq 'belongs') {
135 0           $hints->{Type} = 'belongs';
136 0           $url = "/module/$dist";
137             last CMD
138 0           }
139              
140 0 0         if ($cmd eq 'changes') {
141 0           $hints->{Type} = 'changes';
142 0           $url = "/module/$dist";
143             last CMD
144 0           }
145              
146 0           broadcast( 'message', $msg->context, $msg->channel,
147             "Unknown query; $HelpText"
148             );
149             }
150              
151 0 0         $self->_request($url, $hints) if defined $hints->{Type};
152              
153 0           PLUGIN_EAT_ALL
154             }
155              
156             sub _request {
157 0     0     my ($self, $url, $hints) = @_;
158              
159 0           my $base_url = 'http://api.metacpan.org';
160 0           my $this_url = $base_url . $url;
161              
162 0           logger->debug("metacpan request: $this_url");
163              
164 0           my $request = HTTP::Request->new(GET => $this_url);
165              
166 0           broadcast( 'www_request',
167             $request,
168             'mcpan_plug_resp_recv',
169             $hints
170             );
171             }
172              
173             sub Bot_mcpan_plug_resp_recv {
174 0     0 0   my ($self, $core) = splice @_, 0, 2;
175 0           my $response = ${ $_[1] };
  0            
176 0           my $hints = ${ $_[2] };
  0            
177              
178 0           my $dist = $hints->{Dist};
179 0           my $type = $hints->{Type};
180 0           my $link = $hints->{Link};
181              
182 0 0         unless ($response->is_success) {
183 0           my $status = $response->code;
184 0 0         if ($status == 404) {
185             broadcast( 'message',
186             $hints->{Context}, $hints->{Channel},
187 0           "No such distribution: $dist"
188             );
189             } else {
190             broadcast( 'message',
191             $hints->{Context}, $hints->{Channel},
192 0           "Could not get release info for $dist ($status)"
193             );
194             }
195 0           return PLUGIN_EAT_ALL
196             }
197              
198 0           my $json = $response->content;
199 0 0         unless ($json) {
200             broadcast('message',
201             $hints->{Context}, $hints->{Channel},
202 0           "Unknown failure -- no data received for $dist",
203             );
204 0           return PLUGIN_EAT_ALL
205             }
206              
207             my $d_hash =
208 0     0     try { $Serializer->thaw($json) }
209             catch {
210             broadcast( 'message',
211             $hints->{Context}, $hints->{Channel},
212 0     0     "thaw failure; err: $_",
213             );
214             undef
215 0 0         } or return PLUGIN_EAT_ALL;
  0            
216              
217 0 0 0       unless ($d_hash && ref $d_hash eq 'HASH') {
218             broadcast( 'message',
219             $hints->{Context}, $hints->{Channel},
220 0           "thaw failure for $dist; expected a HASH but got '$d_hash'"
221             );
222 0           return PLUGIN_EAT_ALL
223             }
224              
225 0           my $resp;
226 0           my $prefix = color bold => 'mCPAN';
227              
228             TYPE: {
229              
230 0 0         if ($type eq 'abstract') {
  0            
231 0   0       my $abs = $d_hash->{abstract} || 'No abstract available.';
232 0           my $vers = $d_hash->{version};
233 0           $resp = "$prefix: ($dist $vers) $abs ; $link";
234             last TYPE
235 0           }
236              
237 0 0         if ($type eq 'dist') {
238 0   0       my $dl = $d_hash->{download_url} || 'No download link available.';
239 0           $resp = "$prefix: ($dist) $dl";
240             last TYPE
241 0           }
242              
243 0 0         if ($type eq 'latest') {
244 0           my $vers = $d_hash->{version};
245 0           my $arc = $d_hash->{archive};
246 0           $resp = "$prefix: ($dist) Latest is $vers ($arc) ; $link";
247             last TYPE
248 0           }
249              
250 0 0         if ($type eq 'license') {
251 0           my $name = $d_hash->{name};
252 0 0         my $lic = join ' ', @{ $d_hash->{license}||['undef'] };
  0            
253 0           $resp = "$prefix: License terms for $name: $lic";
254             last TYPE
255 0           }
256              
257 0 0         if ($type eq 'tests') {
258             my %tests = %{
259 0 0         keys %{$d_hash->{tests}||{}} ?
  0            
260             $d_hash->{tests}
261 0 0         : { pass => 0, fail => 0, na => 0, unknown => 0 }
262             };
263              
264 0           my $vers = $d_hash->{version};
265              
266             $resp = sprintf("%s: (%s %s) %d PASS, %d FAIL, %d NA, %d UNKNOWN",
267             $prefix, $dist, $vers,
268             $tests{pass}, $tests{fail}, $tests{na}, $tests{unknown}
269 0           );
270              
271             last TYPE
272 0           }
273              
274 0 0         if ($type eq 'belongs') {
275 0           my $release = $d_hash->{release};
276 0           $resp = "$prefix: $dist belongs to release $release";
277             last TYPE
278 0           }
279              
280 0 0         if ($type eq 'changes') {
281 0           my $release = $d_hash->{release};
282 0           my $actuald = substr $release, 0, rindex $release, '-';
283 0           my $link = "https://www.metacpan.org/changes/distribution/$actuald";
284 0           $resp = "$prefix: Changes for $release: $link";
285             last TYPE
286 0           }
287              
288 0           logger->error("BUG; fell through in response handler");
289             }
290              
291             broadcast( 'message',
292             $hints->{Context}, $hints->{Channel},
293 0 0         $resp
294             ) if $resp;
295              
296 0           PLUGIN_EAT_ALL
297             }
298              
299             1;
300             __END__