lita-standup 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 054576099918534324c7f0c06c0085749fecb790
4
+ data.tar.gz: 5a23fe83f69bc7f2d3d40a253e399a371e19dd3c
5
+ SHA512:
6
+ metadata.gz: 6a3becd29f96564c3bce0c9dd1b413f74ca42b42fb2613f112efe7debd6ff89228f1a289907f0a6261f93b87bbec1e0c7a36aef0167db267ea7151d853ba7af6
7
+ data.tar.gz: ae21d259b76e6501056a1ae29c8d6abca951482850c35a4a62e12bc6d8fe40df937b3d8a4386847f680b7759e9fb1fb903c904abfb94324c82cfbfd9fac71b5a
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.travis.yml ADDED
@@ -0,0 +1,8 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ script: bundle exec rake
5
+ before_install:
6
+ - gem update --system
7
+ services:
8
+ - redis-server
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "byebug"
4
+ gem "sucker_punch"
5
+ gem "mail"
6
+
7
+ gemspec
data/README.md ADDED
@@ -0,0 +1,58 @@
1
+ # lita-standup
2
+
3
+ [![Build Status](https://travis-ci.org/chriswoodrich/lita-standup.png?branch=master)](https://travis-ci.org/chriswoodrich/lita-standup)
4
+ [![Coverage Status](https://coveralls.io/repos/chriswoodrich/lita-standup/badge.png)](https://coveralls.io/r/chriswoodrich/lita-standup)
5
+
6
+ Lita-standup is a handler for Lita, meant to automate the process of the daily standup, and help teams collaborate.
7
+
8
+ ## Installation
9
+
10
+ Add lita-standup to your Lita instance's Gemfile:
11
+
12
+ ``` ruby
13
+ gem "lita-standup"
14
+ ```
15
+
16
+ ## Configuration
17
+
18
+ There's a lot here to configure. Add the following to your ```lita_config.rb``` and interpolate your credentials as needed.
19
+
20
+ ``` ruby
21
+
22
+ Lita.configure do |config|
23
+
24
+ # General settings
25
+ config.handlers.standup.time_to_respond = 60 # type: Integer, default: 60 (minutes)
26
+ config.handlers.standup.summary_email_recipients = ['you@company.com', 'me@company.com'] # type: Array, required: true
27
+ config.handlers.standup.name_of_auth_group = :standup_participants # type: Symbol, required: true
28
+
29
+ ## SMTP Mailer settings
30
+ config.handlers.standup.address = 'smtp.gmail.com' # type: String, required: true
31
+ config.handlers.standup.port = 587 # type: Integer, required: true
32
+ config.handlers.standup.domain = 'your.host.name' # type: String, required: true
33
+ config.handlers.standup.user_name = 'xxxxxxxxxx' # type: String, required: true
34
+ config.handlers.standup.password = 'xxxxxxxxxx' # type: String, required: true
35
+ config.handlers.standup.authentication = 'plain' # type: String, required: true
36
+ config.handlers.standup.enable_starttls_auto = true # type: true || false, required: true
37
+
38
+ end
39
+
40
+
41
+ ```
42
+
43
+
44
+ ## Usage
45
+
46
+ After you're properly configured, manage the auth groups you'll need to use this gem. Add yourself (or whoever else will start the standup) to the auth group ```:standup_admins``` and all participants to the auth group ```:standup_participants``` (unless you overrode this default in the config.)
47
+
48
+ To start the standup, give Lita the command ```Lita: start standup now```.
49
+
50
+ You'll get a private message asking for your answer. Reply in the typical format (using numbers and colons) with 1: things you worked on yesterday, 2: things you'll be doing today, and 3: anything that's blocking you. Example :```Lita: standup response 1: Finished this gem. 2: Make these docs a little better. 3: Wife is making cookies and it's hard to focus.```
51
+
52
+ After the ```time_to_respond``` has elapsed, Lita will compile an email of the responses and send it to all the people in ```summary_email_recipients```.
53
+
54
+ ## Bugs, Comments, feature requests
55
+
56
+ Please open an issue if you have anything to add.
57
+
58
+
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
@@ -0,0 +1,61 @@
1
+ require 'mail'
2
+ require 'sucker_punch'
3
+
4
+ class SummaryEmailJob
5
+ include SuckerPunch::Job
6
+
7
+ def later(sec, payload)
8
+ sec == 0 ? preform(payload) : after(sec) { preform(payload) } #0 seconds not handled well by #after
9
+ end
10
+
11
+ def preform(payload)
12
+ redis = payload[:redis]
13
+ config = payload[:config]
14
+
15
+ email_body = build_email_body_from_redis(redis)
16
+ options = { address: config.address,
17
+ port: config.port,
18
+ domain: config.domain,
19
+ user_name: config.user_name,
20
+ password: config.password,
21
+ authentication: config.authentication,
22
+ enable_starttls_auto: config.enable_starttls_auto}
23
+
24
+ Mail.defaults do
25
+ ENV['MODE'] == 'test' ? dev_meth = ENV['MODE'] : dev_meth = :smtp
26
+ delivery_method(dev_meth , options)
27
+ end
28
+
29
+ if config.email_subject_line == "Standup summary for --today--"
30
+ subject_line = config.email_subject_line.gsub(/--today--/, Time.now.strftime('%m/%d'))
31
+ else
32
+ subject_line = config.email_subject_line
33
+ end
34
+
35
+ mail = Mail.new do
36
+ from config.robot_email_address
37
+ to ['cwoodrich@gmail.com']
38
+ subject subject_line
39
+ body "#{email_body}"
40
+ end
41
+
42
+ if mail.deliver!
43
+ Lita.logger.info("Sent standup email to #{mail.to} at #{Time.now}")
44
+ redis.keys.each{ |key| redis.del(key) }
45
+ end
46
+ end
47
+
48
+ def build_email_body_from_redis(redis)
49
+ email_body = ''
50
+ response_prefix = Date.parse(redis.get("last_standup_started_at")).strftime('%Y%m%d')
51
+ redis.keys.each do |key|
52
+ if key.to_s.include? response_prefix
53
+ email_body += key.gsub(Date.parse(redis.get("last_standup_started_at")).strftime('%Y%m%d') + '-', "")
54
+ email_body += "\n"
55
+ email_body += MultiJson.load(redis.get(key)).join("\n")
56
+ email_body += "\n"
57
+ end
58
+ end
59
+ email_body
60
+ end
61
+ end
@@ -0,0 +1,68 @@
1
+ module Lita
2
+ module Handlers
3
+ class Standup < Handler
4
+ # General settings
5
+ config :time_to_respond, types: [Integer, Float], default: 60 #minutes
6
+ config :summary_email_recipients, type: Array, default: ['you@company.com'], required: true
7
+ config :name_of_auth_group, type: Symbol, default: :standup_participants, required: true
8
+
9
+ ## SMTP Mailer Settings ##
10
+ config :address, type: String, required: true
11
+ config :port, type: Integer, required: true
12
+ config :domain, type: String, required: true
13
+ config :user_name, type: String, required: true
14
+ config :password, type: String, required: true
15
+ config :authentication, type: String, required: true
16
+ config :enable_starttls_auto, types: [TrueClass, FalseClass], required: true
17
+ config :robot_email_address, type: String, default: 'noreply@lita.com', required: true
18
+ config :email_subject_line, type: String, default: "Standup summary for --today--", required: true #interpolated at runtime
19
+
20
+ route %r{^start standup now}i, :begin_standup, command: true, restrict_to: :standup_admins
21
+ route %r{standup response (1.*)(2.*)(3.*)}i, :process_standup, command: true
22
+
23
+ def begin_standup(request)
24
+ redis.set('last_standup_started_at', Time.now)
25
+ find_and_create_users
26
+ message_all_users
27
+ SummaryEmailJob.new().async.later(config.time_to_respond * 60, {redis: redis, config: config})
28
+ end
29
+
30
+ def process_standup(request)
31
+
32
+ return unless timing_is_right?
33
+ request.reply('Response recorded. Thanks for partipating')
34
+ date_string = Time.now.strftime('%Y%m%d')
35
+ user_name = request.user.name.split(' ').join('_') #lol
36
+ redis.set(date_string + '-' + user_name, request.matches.first)
37
+ end
38
+
39
+ private
40
+
41
+ def message_all_users
42
+ @users.each do |user|
43
+ robot.send_message(user, "Time for standup!")
44
+ robot.send_message(user, "Please tell me what you did yesterday,
45
+ what you're doing now, and what you're
46
+ working on today. Please prepend your
47
+ answer with 'standup response'")
48
+ end
49
+ end
50
+
51
+ def find_and_create_users
52
+ @users = robot.auth.groups_with_users[:standup_participants]
53
+ Lita.logger.debug(@users.inspect)
54
+ end
55
+
56
+ def timing_is_right?
57
+ return false if redis.get('last_standup_started_at').nil?
58
+ intitiated_at = Time.parse(redis.get('last_standup_started_at'))
59
+ Time.now > intitiated_at && intitiated_at + (60*config.time_to_respond) > Time.now
60
+ end
61
+
62
+ end
63
+ Lita.register_handler(Standup)
64
+ end
65
+ end
66
+
67
+
68
+
@@ -0,0 +1,14 @@
1
+ require "lita"
2
+
3
+ Lita.load_locales Dir[File.expand_path(
4
+ File.join("..", "..", "locales", "*.yml"), __FILE__
5
+ )]
6
+
7
+ require "lita/handlers/standup"
8
+ require "lita/email_job"
9
+
10
+
11
+ Lita::Handlers::Standup.template_root File.expand_path(
12
+ File.join("..", "..", "templates"),
13
+ __FILE__
14
+ )
@@ -0,0 +1,28 @@
1
+ Gem::Specification.new do |spec|
2
+ spec.name = "lita-standup"
3
+ spec.version = "0.0.1"
4
+ spec.authors = ["Chris Woodrich"]
5
+ spec.email = ["cwoodrich@gmail.com"]
6
+ spec.description = "Daily standup automation for easier collaboration"
7
+ spec.summary = "Daily standup automation for easier collaboration"
8
+ spec.homepage = "https://github.com/chriswoodrich/lita-standup"
9
+ spec.license = "MIT"
10
+ spec.metadata = { "lita_plugin_type" => "handler" }
11
+
12
+ spec.files = `git ls-files`.split($/)
13
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
14
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
15
+ spec.require_paths = ["lib"]
16
+
17
+ spec.add_runtime_dependency "lita", ">= 4.0"
18
+ spec.add_runtime_dependency "sucker_punch"
19
+ spec.add_runtime_dependency "mail"
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "pry-byebug"
23
+ spec.add_development_dependency "rake"
24
+ spec.add_development_dependency "rack-test"
25
+ spec.add_development_dependency "rspec", ">= 3.0.0"
26
+ spec.add_development_dependency "simplecov"
27
+ spec.add_development_dependency "coveralls"
28
+ end
data/locales/en.yml ADDED
@@ -0,0 +1,4 @@
1
+ en:
2
+ lita:
3
+ handlers:
4
+ standup:
@@ -0,0 +1,56 @@
1
+ require "spec_helper"
2
+
3
+ describe Lita::Handlers::Standup, lita_handler: true do
4
+
5
+ it { is_expected.to route_command("start standup now").with_authorization_for(:standup_admins).to(:begin_standup) }
6
+ it { is_expected.to route_command("standup response 1:a2:b3:c").to(:process_standup) }
7
+
8
+ jimmy = Lita::User.create(111, name: "Jimmy")
9
+ tristan = Lita::User.create(112, name: "Tristan")
10
+ mitch = Lita::User.create(113, name: "Mitch")
11
+ people = [jimmy, tristan, mitch]
12
+
13
+ before do
14
+ registry.config.handlers.standup.time_to_respond = 0 #Not async for testing
15
+ registry.config.handlers.standup.address = 'smtp.gmail.com'
16
+ registry.config.handlers.standup.port = 587
17
+ registry.config.handlers.standup.domain = 'your.host.name'
18
+ registry.config.handlers.standup.user_name = ENV['USERNAME']
19
+ registry.config.handlers.standup.password = ENV['PASSWORD']
20
+ registry.config.handlers.standup.authentication = 'plain'
21
+ registry.config.handlers.standup.enable_starttls_auto = true
22
+ people.each { |person| robot.auth.add_user_to_group!(person, :standup_participants) }
23
+ people.each { |person| robot.auth.add_user_to_group!(person, :standup_admins) }
24
+ end
25
+
26
+ describe '#begin_standup' do
27
+ it 'messages each user and prompts for stand up options' do
28
+ send_command("start standup now", as: jimmy)
29
+ expect(replies.size).to eq(6) #Jimmy, Tristan, and Mitch
30
+ end
31
+
32
+ it 'properly queues an email job upon initiation' do
33
+ registry.config.handlers.standup.email_subject_line = "This is a test of Lita-Standup"
34
+ registry.config.handlers.standup.time_to_respond = 60
35
+ send_command("start standup now", as: jimmy)
36
+ send_command("standup response 1: everything 2:everything else 3:nothing", as: jimmy)
37
+ expect(Celluloid::Actor.registered.first.to_s).to end_with("summary_email_job")
38
+ end
39
+ end
40
+
41
+ describe '#process_standup' do
42
+ it 'Emails a compendium of responses out after users reply' do
43
+ registry.config.handlers.standup.time_to_respond = (1.0/60.0)
44
+ send_command("start standup now", as: jimmy)
45
+ send_command("standup response 1: linguistics 2: more homework 3: being in seattle", as: tristan)
46
+ send_command("standup response 1: stitchfix 2: more stitchfix 3: gaining weight", as: mitch)
47
+ send_command("standup response 1: lita 2: Rust else 3: nothing", as: jimmy)
48
+ sleep(2);
49
+ expect(Mail::TestMailer.deliveries.last.body.raw_source).to include "Tristan\n1: linguistics \n2: more homework \n3: being in seattle\n"
50
+ expect(Mail::TestMailer.deliveries.last.body.raw_source).to include "Jimmy\n1: lita \n2: Rust else \n3: nothing\n"
51
+ expect(Mail::TestMailer.deliveries.last.body.raw_source).to include "Mitch\n1: stitchfix \n2: more stitchfix \n3: gaining weight\n"
52
+ end
53
+ it { should have_sent_email.with_subject("Standup summary for #{Time.now.strftime('%m/%d')}") }
54
+ end
55
+
56
+ end
@@ -0,0 +1,16 @@
1
+ require "simplecov"
2
+ require "coveralls"
3
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
4
+ SimpleCov::Formatter::HTMLFormatter,
5
+ Coveralls::SimpleCov::Formatter
6
+ ]
7
+ SimpleCov.start { add_filter "/spec/" }
8
+
9
+ ENV["MODE"]="test"
10
+ require 'sucker_punch/testing/inline'
11
+ require "lita-standup"
12
+ require "lita/rspec"
13
+ include Mail::Matchers
14
+ # A compatibility mode is provided for older plugins upgrading from Lita 3. Since this plugin
15
+ # was generated with Lita 4, the compatibility mode should be left disabled.
16
+ Lita.version_3_compatibility_mode = false
File without changes
metadata ADDED
@@ -0,0 +1,200 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lita-standup
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Chris Woodrich
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-05-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: lita
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '4.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '4.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: sucker_punch
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: mail
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.3'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.3'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry-byebug
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rack-test
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rspec
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: 3.0.0
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: 3.0.0
125
+ - !ruby/object:Gem::Dependency
126
+ name: simplecov
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: coveralls
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ description: Daily standup automation for easier collaboration
154
+ email:
155
+ - cwoodrich@gmail.com
156
+ executables: []
157
+ extensions: []
158
+ extra_rdoc_files: []
159
+ files:
160
+ - ".gitignore"
161
+ - ".travis.yml"
162
+ - Gemfile
163
+ - README.md
164
+ - Rakefile
165
+ - lib/lita-standup.rb
166
+ - lib/lita/email_job.rb
167
+ - lib/lita/handlers/standup.rb
168
+ - lita-standup.gemspec
169
+ - locales/en.yml
170
+ - spec/lita/handlers/standup_spec.rb
171
+ - spec/spec_helper.rb
172
+ - templates/.gitkeep
173
+ homepage: https://github.com/chriswoodrich/lita-standup
174
+ licenses:
175
+ - MIT
176
+ metadata:
177
+ lita_plugin_type: handler
178
+ post_install_message:
179
+ rdoc_options: []
180
+ require_paths:
181
+ - lib
182
+ required_ruby_version: !ruby/object:Gem::Requirement
183
+ requirements:
184
+ - - ">="
185
+ - !ruby/object:Gem::Version
186
+ version: '0'
187
+ required_rubygems_version: !ruby/object:Gem::Requirement
188
+ requirements:
189
+ - - ">="
190
+ - !ruby/object:Gem::Version
191
+ version: '0'
192
+ requirements: []
193
+ rubyforge_project:
194
+ rubygems_version: 2.4.3
195
+ signing_key:
196
+ specification_version: 4
197
+ summary: Daily standup automation for easier collaboration
198
+ test_files:
199
+ - spec/lita/handlers/standup_spec.rb
200
+ - spec/spec_helper.rb