bender-bot 0.0.3 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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