bender-bot 0.0.3 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/lib/bender/bot.rb +98 -18
  4. metadata +1 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6194220e4bd4031c46110f96d78da9826c16cf93
4
- data.tar.gz: 90d5e15752537eec532c8e16831b522d6cf11b49
3
+ metadata.gz: 2eff1d2551be6a4039e117067c97b71a246488bc
4
+ data.tar.gz: 9b7f0a4415aa65ce54a69c28ee873db38811d706
5
5
  SHA512:
6
- metadata.gz: 1928c523bb4dc16565342b5ef31df04cd636db1c59b4732cf7f5d6b8d676e291600dbefe31fac0cb5172196301773c26600851f7233b4c033dfd059eab2ecb4e
7
- data.tar.gz: 3b1ff85103c748808b1ef187628ba62dc719f0e20ebfb794ed263fcf9df3ad1be50990dccbea77df03abef3a60e9fb674d1623a25d0d07ab70efd18de4376025
6
+ metadata.gz: be3ff23c1ed7b956262236ccfd94596d88a97ad027dc7c9643accad7a7a60f4dbf808698275700092af2d000bd0a0753a736e2766757842c0573d71456e2071a
7
+ data.tar.gz: 8436e940e11db1d586ad20fe783a6321dd705be6319141a4b657b06f96fbe0fce6230b155f225a4cdbd7a2e6f6a78986d861ea599fa56e8a5e0c585a7ff9e15a
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.3
1
+ 0.1.0
@@ -28,6 +28,16 @@ class BenderBot
28
28
 
29
29
  JARO = FuzzyStringMatch::JaroWinkler.create :native
30
30
 
31
+ CLOSE_TRANSITIONS = %w[ 21 41 ]
32
+
33
+ SEVERITIES = {
34
+ 1 => '10480',
35
+ 2 => '10481',
36
+ 3 => '10482',
37
+ 4 => '10483',
38
+ 5 => '10484'
39
+ }
40
+
31
41
  SHOW_FIELDS = {
32
42
  'summary' => 'Summary',
33
43
  'description' => 'Description',
@@ -63,23 +73,44 @@ class BenderBot
63
73
  '?inc - This help text',
64
74
  '/inc - List open incidents',
65
75
  '/inc NUM - Show incident details',
66
- '/inc close NUM - Close an indident',
76
+ '/inc close NUM - Close an incident',
67
77
  '/inc SEVERITY SUMMARY - File a new incident',
68
- '/inc summary - Summarize recent indicents'
78
+ '/inc summary - Summarize recent incidents'
69
79
  ].join("\n")
70
80
 
71
81
  when /^\s*\/inc\s*$/
72
82
  refresh_incidents
73
83
 
74
84
  is = store['incidents'].map do |i|
75
- '%s: %s' % [ i['num'], i['fields']['summary'] ]
76
- end.join("\n")
85
+ status = normalize_value i['fields']['status']
86
+ unless status =~ /done|complete|closed/i
87
+ '%s: %s' % [ i['num'], i['fields']['summary'] ]
88
+ end
89
+ end.compact.join("\n")
77
90
 
78
91
  reply is
79
92
 
80
93
  when /^\s*\/inc\s+summary\s*$/
81
- # TODO
82
- reply "Sorry, I haven't been programmed for that yet!"
94
+ refresh_incidents
95
+
96
+ severity_field = SHOW_FIELDS.key 'Severity'
97
+ severities = Hash.new { |h,k| h[k] = [] }
98
+
99
+ store['incidents'].each do |i|
100
+ if recent_incident? i
101
+ repr = '%s-%s: %s' % [
102
+ options.jira_project, i['num'], i['fields']['summary']
103
+ ]
104
+ sev = i['fields'][severity_field]['value']
105
+ severities[sev] << repr
106
+ end
107
+ end
108
+
109
+ is = severities.keys.sort.map do |sev|
110
+ "%s:\n%s" % [ sev, severities[sev].join("\n") ]
111
+ end.join("\n\n")
112
+
113
+ reply is
83
114
 
84
115
  when /^\s*\/inc\s+(\d+)\s*$/
85
116
  refresh_incidents
@@ -96,31 +127,30 @@ class BenderBot
96
127
  end
97
128
  end.compact
98
129
 
99
- reply "%s: %s\n%s" % [
130
+ reply "%s\n%s: %s\n%s" % [
131
+ (options.jira_site + '/browse/' + incident['key']),
100
132
  incident['key'],
101
133
  incident['fields']['summary'],
102
134
  i.join("\n")
103
135
  ]
104
136
 
105
137
  when /^\s*\/inc\s+close\s+(\d+)\s*$/
106
- # TODO
107
- reply "Sorry, I haven't been programmed for that yet!"
108
-
109
- when /^\s*\/inc\s+(\d+)\s+(.*?)\s*$/
110
138
  refresh_incidents
111
139
  incident = store['incidents'].select { |i| i['num'] == $1 }.first
112
- val = incident['fields'][$2]
113
- val = val.is_a?(Hash) ? val['name'] : val
114
- reply val
115
140
 
116
- when /^\s*\/inc\s+(.*?)\s*$/
141
+ reply close_incident(incident)
142
+
143
+ when /^\s*\/inc\s+(sev|s|p)?(\d+)\s+(.*?)\s*$/i
117
144
  user = user_where name: sender
118
145
  data = {
119
146
  fields: {
120
147
  project: { key: options.jira_project },
121
148
  issuetype: { name: options.jira_type },
122
149
  reporter: { name: user[:nick] },
123
- summary: $1
150
+ summary: $3,
151
+ SHOW_FIELDS.key('Severity') => {
152
+ id: SEVERITIES[$2.to_i]
153
+ }
124
154
  }
125
155
  }
126
156
 
@@ -160,7 +190,7 @@ private
160
190
  def refresh_incidents
161
191
  req_path = '/rest/api/2/search'
162
192
  req_params = QueryParams.encode \
163
- jql: "project = #{options.jira_project} AND resolution = Unresolved ORDER BY created ASC, priority DESC",
193
+ jql: "project = #{options.jira_project} ORDER BY created ASC, priority DESC",
164
194
  fields: SHOW_FIELDS.keys.join(','),
165
195
  startAt: 0,
166
196
  maxResults: 1_000_000
@@ -193,13 +223,51 @@ private
193
223
  req['Accept'] = 'application/json'
194
224
  req.body = data.to_json
195
225
 
196
- resp = http.request req
226
+ resp = http.request req
197
227
  issue = JSON.parse(resp.body)
198
228
 
199
229
  return options.jira_site + '/browse/' + issue['key']
200
230
  end
201
231
 
202
232
 
233
+ def close_incident incident
234
+ req_path = '/rest/api/2/issue/%s/transitions?expand=transitions.fields' % [
235
+ incident['key']
236
+ ]
237
+ uri = URI(options.jira_site + req_path)
238
+ http = Net::HTTP.new uri.hostname, uri.port
239
+
240
+ req = Net::HTTP::Post.new uri
241
+ req.basic_auth options.jira_user, options.jira_pass
242
+ req['Content-Type'] = 'application/json'
243
+ req['Accept'] = 'application/json'
244
+
245
+ closed = false
246
+ CLOSE_TRANSITIONS.each do |tid|
247
+ req.body = {
248
+ transition: { id: tid }
249
+ }.to_json
250
+ resp = http.request req
251
+ case resp
252
+ when Net::HTTPBadRequest
253
+ next
254
+ else
255
+ closed = true
256
+ break
257
+ end
258
+ end
259
+
260
+ if closed
261
+ 'Closed: ' + options.jira_site + '/browse/' + incident['key']
262
+ else
263
+ [
264
+ "Failed to close, make sure you've got the ticket filled out",
265
+ (options.jira_site + '/browse/' + incident['key'])
266
+ ].join("\n")
267
+ end
268
+ end
269
+
270
+
203
271
  def normalize_value val
204
272
  case val
205
273
  when Hash
@@ -213,8 +281,20 @@ private
213
281
  end
214
282
  end
215
283
 
284
+
216
285
  def normalize_date val
217
286
  Time.parse(val).utc.iso8601(3).sub(/Z$/, 'UTC')
218
287
  end
219
288
 
289
+
290
+ def recent_incident? i
291
+ it = Time.parse(i['fields']['created'])
292
+ Time.now - it < one_day
293
+ end
294
+
295
+
296
+ def one_day
297
+ 24 * 60 * 60 # seconds/day
298
+ end
299
+
220
300
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bender-bot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sean Clemmer