File Coverage

blib/lib/Hubot/Scripts/bugzilla.pm
Criterion Covered Total %
statement 22 51 43.1
branch 0 4 0.0
condition 0 2 0.0
subroutine 8 13 61.5
pod n/a
total 30 70 42.8


line stmt bran cond sub pod time code
1             package Hubot::Scripts::bugzilla;
2             $Hubot::Scripts::bugzilla::VERSION = '0.1.10';
3 1     1   1842 use utf8;
  1         7  
  1         4  
4 1     1   23 use strict;
  1         1  
  1         22  
5 1     1   3 use warnings;
  1         1  
  1         17  
6 1     1   13896 use JSON;
  1         5719  
  1         4  
7 1     1   763 use URI;
  1         3591  
  1         713  
8              
9             my %PRIORITY_MAP = (
10             '---' => '☆☆☆☆☆',
11             Lowest => '★☆☆☆☆',
12             Low => '★★☆☆☆',
13             Normal => '★★★☆☆',
14             High => '★★★★☆',
15             Highest => '★★★★★',
16             );
17              
18             sub load {
19 0     0     my $client = JSONRPC->new( { url => $ENV{HUBOT_BZ_JSONPRC_URL} } );
20              
21 0           my ( $class, $robot ) = @_;
22             $robot->hear(
23             qr/b(?:ug|z) ([0-9a-z-A-Z ]+)/i,
24             sub {
25 0     0     my $msg = shift;
26 0           for my $query ( split / /, $msg->match->[0] ) {
27             $client->call(
28             'Bug.get',
29             { ids => [$query] },
30             sub {
31 0           my ( $body, $hdr ) = @_;
32 0           speak_bug( $msg, $body, $hdr, $client );
33             }
34 0           );
35             }
36             }
37 0           );
38              
39             $robot->hear(
40             qr/^b(?:ug|z) search (.+)/,
41             sub {
42 0     0     my $msg = shift;
43             $client->call(
44             'Bug.search',
45             { summary => $msg->match->[0] },
46             sub {
47 0           my ( $body, $hdr ) = @_;
48 0           speak_bug( $msg, $body, $hdr, $client );
49             }
50 0           );
51             }
52 0           );
53              
54             $robot->hear(
55             qr/show_bug\.cgi\?id=([0-9]+)/,
56             sub {
57 0     0     my $msg = shift;
58 0           $msg->message->finish;
59             $client->call(
60             'Bug.get',
61             { ids => [$msg->match->[0]] },
62             sub {
63 0           my ( $body, $hdr ) = @_;
64 0           speak_bug( $msg, $body, $hdr, $client );
65             }
66 0           );
67             }
68 0           );
69             }
70              
71             sub speak_bug {
72 0     0     my ( $msg, $body, $hdr, $client ) = @_;
73 0           my $data = decode_json($body);
74 0   0       my $bug = @{ $data->{result}{bugs} ||= [] }[0];
  0            
75              
76 0 0         if ($bug) {
77 0           $msg->send(
78             sprintf "#%s [%s-%s] %s - [%s, %s, %s]",
79             $bug->{id},
80             $bug->{product},
81             $bug->{component},
82             $bug->{summary},
83             $bug->{status},
84             $bug->{assigned_to},
85             $PRIORITY_MAP{ $bug->{priority} }
86             );
87              
88 0 0         if ( $client->{quickserarch_url} ) {
89 0           $msg->send( sprintf $client->{quickserarch_url}, $bug->{id} );
90             }
91             }
92             }
93              
94             package JSONRPC;
95             $JSONRPC::VERSION = '0.1.10';
96 1     1   8 use strict;
  1         2  
  1         35  
97 1     1   5 use warnings;
  1         3  
  1         41  
98 1     1   420 use AnyEvent::HTTP::ScopedClient;
  0            
  0            
99             use JSON::XS;
100              
101             sub new {
102             my ( $class, $ref ) = @_;
103             $ref->{http} = AnyEvent::HTTP::ScopedClient->new( $ref->{url} );
104             $ref->{username} ||= $ENV{HUBOT_BZ_USERNAME};
105             $ref->{password} ||= $ENV{HUBOT_BZ_PASSWORD};
106              
107             my $u = URI->new( $ref->{url} );
108             if ( $u->path eq '/jsonrpc.cgi' ) {
109             $u->path('/buglist.cgi');
110             $u->query('quicksearch=%s');
111             $ref->{quickserarch_url} = $u;
112             }
113              
114             my $self = bless $ref, $class;
115             $self->login if $ref->{username} && $ref->{password};
116             return $self;
117             }
118              
119             sub call {
120             my ( $self, $method, $params, $cb ) = @_;
121             $params->{Bugzilla_token} = $self->{token} if $self->{token};
122             $params = encode_json(
123             { method => $method, params => $params, version => '1.1' } );
124             $self->{http}->header(
125             {
126             cookie => $self->{cookie} || '',
127             Accept => 'application/json',
128             'Content-Type' => 'application/json',
129             'User-Agent' => 'p5-hubot-bugzilla-script-jsonrpc-client',
130             }
131             )->post(
132             $params,
133             sub {
134             my ( $body, $hdr ) = @_;
135             $cb->( $body, $hdr ) if $hdr->{Status} =~ m/^2/;
136             }
137             );
138             }
139              
140             sub set_cookies_or_token {
141             my ( $self, $hdr, $body ) = @_;
142             if ( $hdr->{'set-cookie'} ) {
143             $self->set_cookies($hdr);
144             }
145             else {
146             my $data = decode_json($body);
147             $self->set_token( $data->{result}{token} );
148             }
149             }
150              
151             sub set_token {
152             my ( $self, $token ) = @_;
153             $self->{token} = $token;
154             }
155              
156             sub set_cookies {
157             my ( $self, $hdr ) = @_;
158             $self->{cookie} = $hdr->{'set-cookie'};
159             }
160              
161             sub login {
162             my $self = shift;
163             $self->call(
164             'User.login',
165             { login => $self->{username}, password => $self->{password} },
166             sub {
167             my ( $body, $hdr ) = @_;
168             $self->set_cookies_or_token( $hdr, $body );
169             }
170             );
171             }
172              
173             1;
174              
175             =head1 NAME
176              
177             Hubot::Scripts::bugzilla
178              
179             =head1 VERSION
180              
181             version 0.1.10
182              
183             =head1 SYNOPSIS
184              
185             bug(or bz) (|) - retrun bug summary, status, assignee and priority if exist
186             bug(or bz) search - retrun bug summary, status, assignee and priority if exist
187             bug(or bz) - show the bug title. (support multiple)
188              
189             =head1 CONFIGURATION
190              
191             =over
192              
193             =item * HUBOT_BZ_JSONRPC_URL
194              
195             =item * HUBOT_BZ_USERNAME
196              
197             =item * HUBOT_BZ_PASSWORD
198              
199             =back
200              
201             =head1 AUTHOR
202              
203             Hyungsuk Hong
204              
205             =cut