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.021001';
3 1     1   985 use strictures 2;
  1         9  
  1         36  
4              
5 1     1   174 use Bot::Cobalt;
  1         1  
  1         5  
6 1     1   631 use Bot::Cobalt::Common;
  1         1  
  1         6  
7              
8 1     1   5 use Bot::Cobalt::Serializer;
  1         2  
  1         33  
9             our $Serializer = Bot::Cobalt::Serializer->new('JSON');
10              
11 1     1   376 use HTTP::Request;
  1         622  
  1         20  
12              
13 1     1   2080 use Module::CoreList;
  1         29219  
  1         8  
14              
15 1     1   256 use Try::Tiny;
  1         2  
  1         1453  
16              
17             our $HelpText
18             = 'try: dist, latest, tests, abstract, changes, belongs, license';
19              
20             ## FIXME cachedb?
21              
22 1     1 0 339 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         $dist =~ s/::/-/g unless $cmd eq "belongs";
96 0           my $url = "/release/$dist";
97              
98 0           my $hints = +{
99             Context => $msg->context,
100             Channel => $msg->channel,
101             Nick => $msg->src_nick,
102             Dist => $dist,
103             Link => "http://www.metacpan.org${url}",
104             };
105              
106             CMD: {
107 0 0 0       if ($cmd eq 'latest' || $cmd eq 'release') {
  0            
108 0           $hints->{Type} = 'latest';
109             last CMD
110 0           }
111              
112 0 0         if ($cmd eq 'dist') {
113 0           $hints->{Type} = 'dist';
114             last CMD
115 0           }
116              
117 0 0 0       if ($cmd eq 'test' || $cmd eq 'tests') {
118 0           $hints->{Type} = 'tests';
119             last CMD
120 0           }
121              
122 0 0 0       if ($cmd eq 'info' || $cmd eq 'abstract') {
123 0           $hints->{Type} = 'abstract';
124             last CMD
125 0           }
126              
127 0 0         if ($cmd eq 'license') {
128 0           $hints->{Type} = 'license';
129             last CMD
130 0           }
131              
132 0 0         if ($cmd eq 'belongs') {
133 0           $hints->{Type} = 'belongs';
134 0           $url = "/module/$dist";
135             last CMD
136 0           }
137              
138 0 0 0       if ($cmd eq 'changes' || $cmd eq 'changelog') {
139 0           $hints->{Type} = 'changes';
140 0           $url = "/module/$dist";
141             last CMD
142 0           }
143              
144 0           broadcast( 'message', $msg->context, $msg->channel,
145             "Unknown query; $HelpText"
146             );
147             }
148              
149 0 0         $self->_request($url, $hints) if defined $hints->{Type};
150              
151 0           PLUGIN_EAT_ALL
152             }
153              
154             sub _request {
155 0     0     my ($self, $url, $hints) = @_;
156              
157 0           my $base_url = 'http://api.metacpan.org';
158 0           my $this_url = $base_url . $url;
159              
160 0           logger->debug("metacpan request: $this_url");
161              
162 0           my $request = HTTP::Request->new(GET => $this_url);
163              
164 0           broadcast( 'www_request',
165             $request,
166             'mcpan_plug_resp_recv',
167             $hints
168             );
169             }
170              
171             sub Bot_mcpan_plug_resp_recv {
172 0     0 0   my ($self, $core) = splice @_, 0, 2;
173 0           my $response = ${ $_[1] };
  0            
174 0           my $hints = ${ $_[2] };
  0            
175              
176 0           my $dist = $hints->{Dist};
177 0           my $type = $hints->{Type};
178 0           my $link = $hints->{Link};
179              
180 0 0         unless ($response->is_success) {
181 0           my $status = $response->code;
182 0 0         if ($status == 404) {
183             broadcast( 'message',
184             $hints->{Context}, $hints->{Channel},
185 0           "No such distribution: $dist"
186             );
187             } else {
188             broadcast( 'message',
189             $hints->{Context}, $hints->{Channel},
190 0           "Could not get release info for $dist ($status)"
191             );
192             }
193 0           return PLUGIN_EAT_ALL
194             }
195              
196 0           my $json = $response->content;
197 0 0         unless ($json) {
198             broadcast('message',
199             $hints->{Context}, $hints->{Channel},
200 0           "Unknown failure -- no data received for $dist",
201             );
202 0           return PLUGIN_EAT_ALL
203             }
204              
205             my $d_hash =
206 0     0     try { $Serializer->thaw($json) }
207             catch {
208             broadcast( 'message',
209             $hints->{Context}, $hints->{Channel},
210 0     0     "thaw failure; err: $_",
211             );
212             undef
213 0 0         } or return PLUGIN_EAT_ALL;
  0            
214              
215 0 0 0       unless ($d_hash && ref $d_hash eq 'HASH') {
216             broadcast( 'message',
217             $hints->{Context}, $hints->{Channel},
218 0           "thaw failure for $dist; expected a HASH but got '$d_hash'"
219             );
220 0           return PLUGIN_EAT_ALL
221             }
222              
223 0           my $resp;
224 0           my $prefix = color bold => 'mCPAN';
225              
226             TYPE: {
227              
228 0 0         if ($type eq 'abstract') {
  0            
229 0   0       my $abs = $d_hash->{abstract} || 'No abstract available.';
230 0           my $vers = $d_hash->{version};
231 0           $resp = "$prefix: ($dist $vers) $abs ; $link";
232             last TYPE
233 0           }
234              
235 0 0         if ($type eq 'dist') {
236 0   0       my $dl = $d_hash->{download_url} || 'No download link available.';
237 0           $resp = "$prefix: ($dist) $dl";
238             last TYPE
239 0           }
240              
241 0 0         if ($type eq 'latest') {
242 0           my $vers = $d_hash->{version};
243 0           my $arc = $d_hash->{archive};
244 0           $resp = "$prefix: ($dist) Latest is $vers ($arc) ; $link";
245             last TYPE
246 0           }
247              
248 0 0         if ($type eq 'license') {
249 0           my $name = $d_hash->{name};
250 0 0         my $lic = join ' ', @{ $d_hash->{license}||['undef'] };
  0            
251 0           $resp = "$prefix: License terms for $name: $lic";
252             last TYPE
253 0           }
254              
255 0 0         if ($type eq 'tests') {
256             my %tests = %{
257 0 0         keys %{$d_hash->{tests}||{}} ?
  0            
258             $d_hash->{tests}
259 0 0         : { pass => 0, fail => 0, na => 0, unknown => 0 }
260             };
261              
262 0           my $vers = $d_hash->{version};
263              
264             $resp = sprintf("%s: (%s %s) %d PASS, %d FAIL, %d NA, %d UNKNOWN",
265             $prefix, $dist, $vers,
266             $tests{pass}, $tests{fail}, $tests{na}, $tests{unknown}
267 0           );
268              
269             last TYPE
270 0           }
271              
272 0 0         if ($type eq 'belongs') {
273 0           my $release = $d_hash->{release};
274 0           $resp = "$prefix: $dist belongs to release $release";
275             last TYPE
276 0           }
277              
278 0 0         if ($type eq 'changes') {
279 0           my $release = $d_hash->{release};
280 0           my $actuald = substr $release, 0, rindex $release, '-';
281 0           my $link = "https://www.metacpan.org/changes/distribution/$actuald";
282 0           $resp = "$prefix: Changes for $release: $link";
283             last TYPE
284 0           }
285              
286 0           logger->error("BUG; fell through in response handler");
287             }
288              
289             broadcast( 'message',
290             $hints->{Context}, $hints->{Channel},
291 0 0         $resp
292             ) if $resp;
293              
294 0           PLUGIN_EAT_ALL
295             }
296              
297             1;
298             __END__