lita-hush 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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f9f0d924e27a9eda4548bd3c77a83516d94edf83
4
+ data.tar.gz: e5f2ec63674d46da2ffce2e86c07448667f6215a
5
+ SHA512:
6
+ metadata.gz: 47c678fca712d15a804a344c8fb8c6d3a8cae234eb21f747ced39c62b4d1ed6246f98432c10302a0dced37303b5b4f194cd0eb6cf76ec5abf8fa5544f363f979
7
+ data.tar.gz: 72cb74b7fdad8b79d594589640c2f7ea966bbfd6dcb1f36833c91bf0de30cf813a60a924812e4ba911bb4ba6e2d47b2235d2ed0814db3824be09f533c12b9af7
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/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color --profile 5
data/.rubocop.yml ADDED
@@ -0,0 +1,10 @@
1
+ ClassLength:
2
+ Max: 150
3
+
4
+ Documentation:
5
+ Exclude:
6
+ - lib/lita/handlers/hush.rb
7
+
8
+ FileName:
9
+ Exclude:
10
+ - lib/lita-hush.rb
data/.travis.yml ADDED
@@ -0,0 +1,8 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1
4
+ - 2.2
5
+ services:
6
+ - redis-server
7
+ sudo: false
8
+ cache: bundler
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/README.md ADDED
@@ -0,0 +1,55 @@
1
+ # lita-hush
2
+
3
+ [![Build Status](https://img.shields.io/travis/esigler/lita-hush/master.svg)](https://travis-ci.org/esigler/lita-hush)
4
+ [![MIT License](https://img.shields.io/badge/license-MIT-brightgreen.svg)](https://tldrlegal.com/license/mit-license)
5
+ [![RubyGems](http://img.shields.io/gem/v/lita-hush.svg)](https://rubygems.org/gems/lita-hush)
6
+ [![Coveralls Coverage](https://img.shields.io/coveralls/esigler/lita-hush/master.svg)](https://coveralls.io/r/esigler/lita-hush)
7
+ [![Code Climate](https://img.shields.io/codeclimate/github/esigler/lita-hush.svg)](https://codeclimate.com/github/esigler/lita-hush)
8
+ [![Gemnasium](https://img.shields.io/gemnasium/esigler/lita-hush.svg)](https://gemnasium.com/esigler/lita-hush)
9
+
10
+ A room moderation plugin for Lita.
11
+
12
+ ## Installation
13
+
14
+ Add lita-hush to your Lita instance's Gemfile:
15
+
16
+ ``` ruby
17
+ gem 'lita-hush'
18
+ ```
19
+
20
+ ## Configuration
21
+
22
+ There are no Lita configuration file entries needed.
23
+
24
+ ## Usage
25
+
26
+ ### Example
27
+
28
+ ```
29
+ @alice in quiet_room> Lita room add @alice
30
+ @alice in quiet_room> Lita room moderation on
31
+ @Lita in quiet_room> Room now moderated
32
+ @alice in quiet_room> Peace and quiet!
33
+ @bob in quiet_room> Hello world!
34
+ @Lita PM to @bob> quiet_room is a moderated room
35
+ ```
36
+
37
+ ### Adding / Removing Someone
38
+
39
+ ```
40
+ room add @user
41
+ room remove @user
42
+ ```
43
+
44
+ ### Moderating / Unmoderating a Room
45
+
46
+ ```
47
+ room moderation on # Automatically adds requestor to approved list
48
+ room moderation off
49
+ ```
50
+
51
+ ### Status
52
+
53
+ ```
54
+ room status
55
+ ```
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+ require 'rubocop/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new(:spec)
6
+ RuboCop::RakeTask.new(:rubocop)
7
+
8
+ task default: [:spec, :rubocop]
data/lib/lita-hush.rb ADDED
@@ -0,0 +1,12 @@
1
+ require 'lita'
2
+
3
+ Lita.load_locales Dir[File.expand_path(
4
+ File.join('..', '..', 'locales', '*.yml'), __FILE__
5
+ )]
6
+
7
+ require 'lita/handlers/hush'
8
+
9
+ Lita::Handlers::Hush.template_root File.expand_path(
10
+ File.join('..', '..', 'templates'),
11
+ __FILE__
12
+ )
@@ -0,0 +1,129 @@
1
+ module Lita
2
+ module Handlers
3
+ class Hush < Handler
4
+ # NOTE: I don't like using catchall matchers. Is there a cleaner way?
5
+ route(
6
+ /.*/,
7
+ :ambient,
8
+ command: false
9
+ )
10
+
11
+ route(
12
+ /^room\s(add|remove)\s(?<user>.*)$/,
13
+ :voice,
14
+ command: true,
15
+ help: {
16
+ t('help.voice.syntax') => t('help.voice.desc')
17
+ }
18
+ )
19
+
20
+ route(
21
+ /^room\smoderation\s(?<toggle>(on|off))$/,
22
+ :moderate,
23
+ command: true,
24
+ help: {
25
+ t('help.moderate.syntax') => t('help.moderate.desc')
26
+ }
27
+ )
28
+
29
+ route(
30
+ /^room\sstatus$/,
31
+ :status,
32
+ command: true,
33
+ help: {
34
+ t('help.status.syntax') => t('help.status.desc')
35
+ }
36
+ )
37
+
38
+ def ambient(response)
39
+ src = response.message.source
40
+ return unless room_moderated?(src.room)
41
+ return if user_has_voice?(src.room, src.user)
42
+ return if response.message.body == 'room status'
43
+
44
+ response.reply_privately(t('ambient.pm', room: src.room_object.name))
45
+ # NOTE: This is the nuclear option, I'd like to give a ramp up at least?
46
+ # response.reply("/kick #{robot.mention_format(src.user)}")
47
+ end
48
+
49
+ def moderate(response)
50
+ src = response.message.source
51
+
52
+ action = if response.match_data['toggle'] == 'on'
53
+ moderate_room(src.room)
54
+ give_voice(src.room, src.user)
55
+ 'moderated'
56
+ else
57
+ unmoderate_room(src.room)
58
+ 'unmoderated'
59
+ end
60
+
61
+ response.reply(t('moderation.complete', action: action))
62
+ end
63
+
64
+ def status(response)
65
+ src = response.message.source
66
+ state = room_moderated?(src.room) ? 'moderated' : 'unmoderated'
67
+
68
+ response.reply(t('status.overview', state: state))
69
+ end
70
+
71
+ def voice(response)
72
+ src = response.message.source
73
+ user = Lita::User.fuzzy_find(response.match_data['user'])
74
+ return response.reply(t('error.nouser')) unless user
75
+
76
+ action = toggle_voice(src.room, user) ? 'added to' : 'removed from'
77
+
78
+ response.reply(t('voice.complete',
79
+ user: user.name,
80
+ room: src.room_object.name,
81
+ action: action))
82
+ end
83
+
84
+ private
85
+
86
+ def give_voice(room, user)
87
+ return if room.nil? || user.nil?
88
+ redis.sadd("voice_list_#{room}", user.id)
89
+ end
90
+
91
+ def moderate_room(room)
92
+ return if room.nil?
93
+ redis.sadd('moderated_rooms', room)
94
+ end
95
+
96
+ def room_moderated?(room)
97
+ return false if room.nil?
98
+ redis.sismember('moderated_rooms', room)
99
+ end
100
+
101
+ def take_voice(room, user)
102
+ return if room.nil? || user.nil?
103
+ redis.srem("voice_list_#{room}", user.id)
104
+ end
105
+
106
+ def toggle_voice(room, user)
107
+ if user_has_voice?(room, user)
108
+ take_voice(room, user)
109
+ false
110
+ else
111
+ give_voice(room, user)
112
+ true
113
+ end
114
+ end
115
+
116
+ def unmoderate_room(room)
117
+ return if room.nil?
118
+ redis.srem('moderated_rooms', room)
119
+ end
120
+
121
+ def user_has_voice?(room, user)
122
+ return false if room.nil? || user.nil?
123
+ redis.sismember("voice_list_#{room}", user.id)
124
+ end
125
+
126
+ Lita.register_handler(self)
127
+ end
128
+ end
129
+ end
data/lita-hush.gemspec ADDED
@@ -0,0 +1,27 @@
1
+ Gem::Specification.new do |spec|
2
+ spec.name = 'lita-hush'
3
+ spec.version = '0.1.0'
4
+ spec.authors = ['Eric Sigler']
5
+ spec.email = ['me@esigler.com']
6
+ spec.description = 'A room moderation plugin for Lita'
7
+ spec.summary = spec.description
8
+ spec.homepage = 'https://github.com/esigler/lita-hush'
9
+ spec.license = 'MIT'
10
+ spec.metadata = { 'lita_plugin_type' => 'handler' }
11
+
12
+ spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
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.7'
18
+
19
+ spec.add_development_dependency 'bundler', '~> 1.3'
20
+ spec.add_development_dependency 'coveralls'
21
+ spec.add_development_dependency 'pry-byebug'
22
+ spec.add_development_dependency 'rake'
23
+ spec.add_development_dependency 'rack-test'
24
+ spec.add_development_dependency 'rspec', '>= 3.0.0'
25
+ spec.add_development_dependency 'rubocop'
26
+ spec.add_development_dependency 'simplecov'
27
+ end
data/locales/en.yml ADDED
@@ -0,0 +1,24 @@
1
+ en:
2
+ lita:
3
+ handlers:
4
+ hush:
5
+ ambient:
6
+ pm: "%{room} is a moderated room"
7
+ error:
8
+ nouser: "That user was not found"
9
+ help:
10
+ voice:
11
+ syntax: room (add|remove) @user
12
+ desc: "Add or remove <user> to room's moderation list"
13
+ moderate:
14
+ syntax: room moderation (on|off)
15
+ desc: Room participants not on the moderation list will be privately messaged
16
+ status:
17
+ syntax: room status
18
+ desc: Shows current moderation status
19
+ moderation:
20
+ complete: Room now %{action}
21
+ status:
22
+ overview: "Room is %{state}"
23
+ voice:
24
+ complete: "%{user} %{action} %{room} list"
@@ -0,0 +1,89 @@
1
+ require 'spec_helper'
2
+
3
+ def verify_hush(occurred)
4
+ expect(replies.include?('quiet_room is a moderated room')).to eq(occurred)
5
+ end
6
+
7
+ describe Lita::Handlers::Hush, lita_handler: true do
8
+ it { is_expected.to route('anything').to(:ambient) }
9
+ it { is_expected.to route_command('room add @foo').to(:voice) }
10
+ it { is_expected.to route_command('room remove @foo').to(:voice) }
11
+ it { is_expected.to route_command('room status').to(:status) }
12
+ it { is_expected.to route_command('room moderation on').to(:moderate) }
13
+ it { is_expected.to route_command('room moderation off').to(:moderate) }
14
+
15
+ let(:alice) do
16
+ Lita::User.create(123, name: 'Alice', mention_name: 'alice')
17
+ end
18
+
19
+ let(:bob) do
20
+ Lita::User.create(456, name: 'Bob', mention_name: 'bob')
21
+ end
22
+
23
+ let(:quiet_room) do
24
+ Lita::Room.new(1, name: 'quiet_room')
25
+ end
26
+
27
+ let(:loud_room) do
28
+ Lita::Room.new(2, name: 'loud_room')
29
+ end
30
+
31
+ before do
32
+ send_command('room moderation on', as: alice, from: quiet_room)
33
+ end
34
+
35
+ describe '#add' do
36
+ it 'adds a user to that rooms list' do
37
+ Lita::User.create(456, name: 'Bob', mention_name: 'bob')
38
+ send_command('room add bob', as: alice, from: quiet_room)
39
+ expect(replies.last).to eq('Bob added to quiet_room list')
40
+ end
41
+ end
42
+
43
+ describe '#ambient' do
44
+ it 'does nothing in rooms that it is not configured for' do
45
+ send_message('foo', as: alice, from: loud_room)
46
+ send_message('foo', as: bob, from: loud_room)
47
+ verify_hush(false)
48
+ end
49
+
50
+ it 'allows people on a list to speak' do
51
+ send_message('foo', as: alice, from: quiet_room)
52
+ verify_hush(false)
53
+ end
54
+
55
+ it 'sends a message to people not on a list when they speak' do
56
+ send_message('bar', as: bob, from: quiet_room)
57
+ verify_hush(true)
58
+ end
59
+ end
60
+
61
+ describe '#remove' do
62
+ it 'removes a user from that rooms list' do
63
+ send_command('room remove alice', as: alice, from: quiet_room)
64
+ expect(replies.last).to eq('Alice removed from quiet_room list')
65
+ end
66
+ end
67
+
68
+ describe '#status' do
69
+ it 'describes the current moderation status of the room' do
70
+ send_command('room status', as: alice, from: quiet_room)
71
+ expect(replies.last).to eq('Room is moderated')
72
+ send_command('room status', as: alice, from: loud_room)
73
+ expect(replies.last).to eq('Room is unmoderated')
74
+ end
75
+
76
+ it 'does not PM if an unapproved user asks in a moderated room' do
77
+ send_command('room status', as: bob, from: quiet_room)
78
+ expect(replies.last).to eq('Room is moderated')
79
+ verify_hush(false)
80
+ end
81
+ end
82
+
83
+ describe '#unmoderate' do
84
+ it 'unmoderates a moderated room' do
85
+ send_command('room moderation off', from: quiet_room)
86
+ expect(replies.last).to eq('Room now unmoderated')
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,29 @@
1
+ require 'simplecov'
2
+ require 'coveralls'
3
+ SimpleCov.formatters = [
4
+ SimpleCov::Formatter::HTMLFormatter,
5
+ Coveralls::SimpleCov::Formatter
6
+ ]
7
+ SimpleCov.start { add_filter '/spec/' }
8
+
9
+ require 'lita-hush'
10
+ require 'lita/rspec'
11
+
12
+ Lita.version_3_compatibility_mode = false
13
+
14
+ RSpec.configure do |config|
15
+ config.expect_with :rspec do |expectations|
16
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
17
+ end
18
+
19
+ config.mock_with :rspec do |mocks|
20
+ mocks.verify_partial_doubles = true
21
+ end
22
+
23
+ config.filter_run :focus
24
+ config.run_all_when_everything_filtered = true
25
+ config.default_formatter = 'doc' if config.files_to_run.one?
26
+ config.order = :random
27
+
28
+ Kernel.srand config.seed
29
+ end
File without changes
metadata ADDED
@@ -0,0 +1,187 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lita-hush
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Eric Sigler
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-02-14 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.7'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '4.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.3'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: coveralls
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
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: pry-byebug
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
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: rack-test
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: rspec
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: 3.0.0
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: 3.0.0
111
+ - !ruby/object:Gem::Dependency
112
+ name: rubocop
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '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
+ description: A room moderation plugin for Lita
140
+ email:
141
+ - me@esigler.com
142
+ executables: []
143
+ extensions: []
144
+ extra_rdoc_files: []
145
+ files:
146
+ - ".gitignore"
147
+ - ".rspec"
148
+ - ".rubocop.yml"
149
+ - ".travis.yml"
150
+ - Gemfile
151
+ - README.md
152
+ - Rakefile
153
+ - lib/lita-hush.rb
154
+ - lib/lita/handlers/hush.rb
155
+ - lita-hush.gemspec
156
+ - locales/en.yml
157
+ - spec/lita/handlers/hush_spec.rb
158
+ - spec/spec_helper.rb
159
+ - templates/.gitkeep
160
+ homepage: https://github.com/esigler/lita-hush
161
+ licenses:
162
+ - MIT
163
+ metadata:
164
+ lita_plugin_type: handler
165
+ post_install_message:
166
+ rdoc_options: []
167
+ require_paths:
168
+ - lib
169
+ required_ruby_version: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ required_rubygems_version: !ruby/object:Gem::Requirement
175
+ requirements:
176
+ - - ">="
177
+ - !ruby/object:Gem::Version
178
+ version: '0'
179
+ requirements: []
180
+ rubyforge_project:
181
+ rubygems_version: 2.5.1
182
+ signing_key:
183
+ specification_version: 4
184
+ summary: A room moderation plugin for Lita
185
+ test_files:
186
+ - spec/lita/handlers/hush_spec.rb
187
+ - spec/spec_helper.rb