ferris-bueller 0.0.0 → 0.0.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bd02010a5690c0772a134273d476c24e292d8b15
4
- data.tar.gz: b0e2d65aaa1b7bd1546c9681c322b4429e4a0f65
3
+ metadata.gz: bdfbffb726a39dad7e3cbef79559e7c00330d53f
4
+ data.tar.gz: 329a4fa79b56b17eb91378bf41d29de2c81c0d5a
5
5
  SHA512:
6
- metadata.gz: 41280791c72f6d5b32861eea7d9c588e533b76dce2485925f498b8a88e5a33dc89f3e959dedc46897350cf215924ce6ed7357598f220d66e8abd355dc8f61391
7
- data.tar.gz: ccdbaefb94e9c4ac5418857913c8db8c862c020f6e22c0c588226bf862313b8285fd565f9e7e4a971739b9f47fa2a11b78835eedc62b8c6d004c8c42877e142e
6
+ metadata.gz: 5cf95d2f4a02faa32358101b05902ecd2accf5dcc82a2a9062d15af11a587d7a1fd5e74f25fa5295bd50e8f0129c45fe586fbb13ae776083343cc1f0dd44d7d9
7
+ data.tar.gz: d386502333cfaf28a1990b2f51ff47db07b48fa8475c6945499ae955dd15e4264c9eb81fd9770a4f73f222954d8ad93b0838cefa0e81dae946e23b231ea8b556
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2015 Sean Clemmer and Blue Jeans Network
1
+ Copyright (c) 2016 Sean Clemmer and Blue Jeans Network
2
2
 
3
3
  Permission to use, copy, modify, and/or distribute this software for any
4
4
  purpose with or without fee is hereby granted, provided that the above
data/Readme.md CHANGED
@@ -1,3 +1,3 @@
1
- # Ferris
1
+ # Ferris Bueller ![Version](https://img.shields.io/gem/v/ferris-bueller.svg?style=flat-square)
2
2
 
3
- TODO
3
+ Successor to [Bender](https://github.com/sczizzo/bender), based on [Ferris](https://github.com/sczizzo/ferris)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.0
1
+ 0.0.1
data/bin/ferris-bueller CHANGED
@@ -1,3 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
2
  require 'ferris-bueller'
3
+ $stdout.sync = true
3
4
  FerrisBueller::Main.start
@@ -1,3 +1,7 @@
1
+ require 'json'
2
+ require 'net/http'
3
+
4
+ require 'ferris'
1
5
  require 'thin/logging'
2
6
  require 'queryparams'
3
7
 
@@ -19,6 +23,8 @@ module FerrisBueller
19
23
  Web.set :bind, options.bind
20
24
  Web.set :store, @store
21
25
  Web.set :logger, log
26
+ Web.set :verification_token, options.verification_token
27
+ Web.set :api, Ferris::API.new(token: options.api_token, logger: log)
22
28
 
23
29
  if log.level >= ::Logger::DEBUG
24
30
  Web.set :raise_errors, true
@@ -21,12 +21,18 @@ module FerrisBueller
21
21
 
22
22
 
23
23
  desc 'start', 'Start Bender HipChat bot and Web server'
24
- option :token, \
24
+ option :api_token, \
25
+ type: :string,
26
+ aliases: %w[ -a ],
27
+ desc: 'Set Slack API token',
28
+ required: true,
29
+ default: ENV['FERRIS_BUELLER_API_TOKEN']
30
+ option :verification_token, \
25
31
  type: :string,
26
32
  aliases: %w[ -t ],
27
- desc: 'Set Slack verificatino token',
33
+ desc: 'Set Slack verification token',
28
34
  required: true,
29
- default: ENV['FERRIS_BUELLER_TOKEN']
35
+ default: ENV['FERRIS_BUELLER_VERIFICATION_TOKEN']
30
36
  option :database, \
31
37
  type: :string,
32
38
  aliases: %w[ -d ],
@@ -0,0 +1,76 @@
1
+ module FerrisBueller
2
+ module Replies
3
+
4
+ def reply_whoami params
5
+ u = user_lookup(params)
6
+ if u
7
+ { text: "You're <@#{params['user_id']}>",
8
+ attachments: [
9
+ {
10
+ title: 'Slack User',
11
+ # pretext: 'User found via Slack APIs',
12
+ text: "```#{JSON.pretty_generate(u[:slack])}```",
13
+ mrkdwn_in: %w[ text pretext ]
14
+ },
15
+ {
16
+ title: 'Jira User',
17
+ # pretext: 'User found via Jira APIs',
18
+ text: "```#{JSON.pretty_generate(u[:jira])}```",
19
+ mrkdwn_in: %w[ text pretext ]
20
+ }
21
+ ]
22
+ }
23
+ else
24
+ {
25
+ text: "You're <@#{params['user_id']}>, but I can't say much more than that"
26
+ }
27
+ end
28
+ end
29
+
30
+
31
+ def reply_help params
32
+ { text: "Help!" }
33
+ end
34
+
35
+
36
+ def reply_dunno params
37
+ { text: "Invalid usage. Try the `help` command" }
38
+ end
39
+
40
+
41
+ def reply_list params
42
+ { text: 'list' }
43
+ end
44
+
45
+
46
+ def reply_summary params
47
+ { text: 'summary' }
48
+ end
49
+
50
+
51
+ def reply_show inc_num, params
52
+ { text: 'show %d' % inc_num }
53
+ end
54
+
55
+
56
+ def reply_resolve inc_num, params
57
+ { text: 'resolve %d' % inc_num }
58
+ end
59
+
60
+
61
+ def reply_close inc_num, params
62
+ { text: 'close %d' % inc_num }
63
+ end
64
+
65
+
66
+ def reply_open sev_num, summary, params
67
+ { text: 'open %d %s' % [ sev_num, summary ] }
68
+ end
69
+
70
+
71
+ def reply_comment inc_num, comment, params
72
+ { text: 'comment %d %s' % [ inc_num, comment ] }
73
+ end
74
+
75
+ end
76
+ end
@@ -1,46 +1,84 @@
1
1
  require 'json'
2
2
 
3
3
  require 'sinatra/base'
4
+ require 'fuzzystringmatch'
4
5
 
5
6
  require_relative 'metadata'
7
+ require_relative 'replies'
8
+ require_relative 'web_helpers'
6
9
 
7
10
  Thread.abort_on_exception = true
8
11
 
9
12
 
10
13
  module FerrisBueller
11
14
  class Web < Sinatra::Application
12
- def log ; settings.logger end
13
- def store ; settings.store end
14
-
15
+ include WebHelpers
16
+ include Replies
15
17
 
16
18
  get '/' do
17
- log.info event: 'get /'
19
+ log.debug event: 'get /'
18
20
  content_type :text
19
21
  'Sup.'
20
22
  end
21
23
 
22
24
 
23
25
  get '/v' do
24
- log.info event: 'get /v'
26
+ log.debug event: 'get /v'
25
27
  content_type :text
26
28
  VERSION
27
29
  end
28
30
 
29
31
 
30
32
  get '/s' do
31
- log.info event: 'get /s'
33
+ log.debug event: 'get /s'
32
34
  content_type :json
33
35
  store.to_json
34
36
  end
35
37
 
36
38
 
37
39
  post '/' do
38
- request.body.rewind
39
- body = request.body.read
40
- log.info event: 'post /', params: params, body: body
41
- # TODO
42
- content_type :json
43
- { params: params, body: body }.to_json
40
+ log.debug event: 'post /', params: params
41
+ unless params['token'] == settings.verification_token
42
+ log.error event: 'verification failed', params: params
43
+ halt 403
44
+ else
45
+ content_type :json
46
+ reply = respond(params)
47
+ JSON.generate reply if reply
48
+ end
49
+ end
50
+
51
+
52
+
53
+ private
54
+
55
+ def respond params
56
+ case params['text'].strip
57
+ when 'whoami'
58
+ reply_whoami params
59
+ when /^help/
60
+ reply_help params
61
+ when ''
62
+ reply_list params
63
+ when 'list'
64
+ reply_list params
65
+ when 'summary'
66
+ reply_summary params
67
+ when /^(\d+)$/
68
+ reply_show $1, params
69
+ when /^show (\d+)/
70
+ reply_show $1, params
71
+ when /^resolve (\d+)/
72
+ reply_resolve $1, params
73
+ when /^close (\d+)/
74
+ reply_close $1, params
75
+ when /^open (\d+) (.*)/m
76
+ reply_open $1, $2, params
77
+ when /^comment (\d+) (.*)/m
78
+ reply_comment $1, $2, params
79
+ else
80
+ reply_dunno params
81
+ end
44
82
  end
45
83
 
46
84
  end
@@ -0,0 +1,69 @@
1
+ module FerrisBueller
2
+ module WebHelpers
3
+
4
+ def store ; settings.store end
5
+
6
+ def log ; settings.logger end
7
+
8
+ def api ; settings.api end
9
+
10
+
11
+ def user_lookup params, threshold=0.75
12
+ data = api.send 'users.info', user: params['user_id']
13
+
14
+ slack_user = {
15
+ key: data['user']['id'],
16
+ name: (data['user']['real_name'] || data['user']['name']),
17
+ nick: data['user']['name'],
18
+ email: data['user']['email']
19
+ }
20
+
21
+ jira_matches = store['jira_users'].values.map do |jira_user|
22
+ distances = [ :name, :nick ].map do |k|
23
+ compare slack_user[k], jira_user[k]
24
+ end.compact
25
+ mean_distance = 1.0 * distances.inject(:+) / distances.size
26
+ if mean_distance > threshold
27
+ { user: jira_user, distance: mean_distance}
28
+ end
29
+ end.compact
30
+
31
+ jira_match = jira_matches.sort_by { |m| m[:distance] }.last
32
+
33
+ unless jira_match
34
+ log.warn \
35
+ event: 'unmatched user',
36
+ slack_user: slack_user
37
+ return nil
38
+ end
39
+
40
+ log.info \
41
+ event: 'matched user',
42
+ slack_user: slack_user,
43
+ jira_match: jira_match
44
+
45
+ return { slack: slack_user, jira: jira_match[:user] }
46
+
47
+ rescue StandardError => e
48
+ log.error \
49
+ error: 'could not lookup users',
50
+ event: 'exception',
51
+ exception: e.inspect,
52
+ class: e.class,
53
+ message: e.message,
54
+ backtrace: e.backtrace
55
+ return nil
56
+ end
57
+
58
+
59
+ def compare name1, name2
60
+ return nil if name1.nil? || name1.empty?
61
+ return nil if name2.nil? || name2.empty?
62
+ @@jaro ||= FuzzyStringMatch::JaroWinkler.create :native
63
+ n1 = name1.gsub(/\W/, '').downcase
64
+ n2 = name2.gsub(/\W/, '').downcase
65
+ @@jaro.getDistance n1, n2
66
+ end
67
+
68
+ end
69
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ferris-bueller
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sean Clemmer
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '1.4'
83
+ - !ruby/object:Gem::Dependency
84
+ name: ferris
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: eventmachine
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -138,7 +152,8 @@ dependencies:
138
152
  version: 1.9.6
139
153
  description: Successor to Bender, based on Ferris.
140
154
  email: sclemmer@bluejeans.com
141
- executables: []
155
+ executables:
156
+ - ferris-bueller
142
157
  extensions: []
143
158
  extra_rdoc_files: []
144
159
  files:
@@ -152,7 +167,9 @@ files:
152
167
  - lib/ferris-bueller/main.rb
153
168
  - lib/ferris-bueller/metadata.rb
154
169
  - lib/ferris-bueller/mjolnir.rb
170
+ - lib/ferris-bueller/replies.rb
155
171
  - lib/ferris-bueller/web.rb
172
+ - lib/ferris-bueller/web_helpers.rb
156
173
  homepage: https://github.com/sczizzo/ferris-bueller
157
174
  licenses:
158
175
  - ISC
@@ -178,4 +195,3 @@ signing_key:
178
195
  specification_version: 4
179
196
  summary: Successor to Bender, based on Ferris
180
197
  test_files: []
181
- has_rdoc: