hipbot 0.2.0 → 1.0.0.rc1

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.
data/.gitignore CHANGED
@@ -1,2 +1,3 @@
1
1
  *.gem
2
- test_bot.rb
2
+ test_bot.rb
3
+ coverage/*
data/Gemfile CHANGED
@@ -11,4 +11,5 @@ gem 'daemons'
11
11
 
12
12
  gem 'rspec'
13
13
  gem 'guard-rspec'
14
+ gem 'coveralls', require: false
14
15
  gem 'mocha'
@@ -6,7 +6,14 @@ GEM
6
6
  multi_json (~> 1.0)
7
7
  addressable (2.3.3)
8
8
  coderay (1.0.9)
9
+ colorize (0.5.8)
9
10
  cookiejar (0.3.0)
11
+ coveralls (0.6.7)
12
+ colorize
13
+ multi_json (~> 1.3)
14
+ rest-client
15
+ simplecov (>= 0.7)
16
+ thor
10
17
  daemons (1.1.9)
11
18
  diff-lcs (1.2.2)
12
19
  em-http-request (1.0.3)
@@ -37,6 +44,7 @@ GEM
37
44
  lumberjack (1.0.3)
38
45
  metaclass (0.0.1)
39
46
  method_source (0.8.1)
47
+ mime-types (1.23)
40
48
  mocha (0.13.3)
41
49
  metaclass (~> 0.0.1)
42
50
  multi_json (1.7.2)
@@ -46,6 +54,8 @@ GEM
46
54
  method_source (~> 0.8)
47
55
  slop (~> 3.4)
48
56
  rake (10.0.4)
57
+ rest-client (1.6.7)
58
+ mime-types (>= 1.16)
49
59
  rspec (2.13.0)
50
60
  rspec-core (~> 2.13.0)
51
61
  rspec-expectations (~> 2.13.0)
@@ -54,6 +64,10 @@ GEM
54
64
  rspec-expectations (2.13.0)
55
65
  diff-lcs (>= 1.1.3, < 2.0)
56
66
  rspec-mocks (2.13.0)
67
+ simplecov (0.7.1)
68
+ multi_json (~> 1.0)
69
+ simplecov-html (~> 0.7.1)
70
+ simplecov-html (0.7.1)
57
71
  slop (3.4.4)
58
72
  thor (0.18.1)
59
73
  xmpp4r (0.5)
@@ -63,6 +77,7 @@ PLATFORMS
63
77
 
64
78
  DEPENDENCIES
65
79
  activesupport
80
+ coveralls
66
81
  daemons
67
82
  em-http-request
68
83
  eventmachine
data/README.md CHANGED
@@ -2,6 +2,9 @@
2
2
 
3
3
  [![Build Status](https://secure.travis-ci.org/pewniak747/hipbot.png?branch=master)](http://travis-ci.org/pewniak747/hipbot)
4
4
  [![Code Climate](https://codeclimate.com/github/pewniak747/hipbot.png)](https://codeclimate.com/github/pewniak747/hipbot)
5
+ [![Coverage Status](https://coveralls.io/repos/pewniak747/hipbot/badge.png?branch=master)](https://coveralls.io/r/pewniak747/hipbot)
6
+ [![Dependency Status](https://gemnasium.com/pewniak747/hipbot.png)](https://gemnasium.com/pewniak747/hipbot)
7
+ [![Gem Version](https://badge.fury.io/rb/hipbot.png)](http://badge.fury.io/rb/hipbot)
5
8
 
6
9
  Hipbot is a XMPP bot for HipChat, written in ruby & eventmachine.
7
10
 
@@ -17,7 +20,7 @@ gem install hipbot
17
20
 
18
21
  Create `bot.rb` file, subclass `Hipbot::Bot` and customize the responses.
19
22
 
20
- ``` ruby
23
+ ```ruby
21
24
  require 'hipbot'
22
25
 
23
26
  class MyCompanyBot < Hipbot::Bot
@@ -27,7 +30,6 @@ class MyCompanyBot < Hipbot::Bot
27
30
  c.password = 'secret' # required
28
31
  c.teams = { vip: ['John', 'Mike'] }
29
32
  c.rooms = { project_rooms: ['Project 1', 'Project 2'] }
30
- c.plugins = [ PluginClass ]
31
33
  end
32
34
 
33
35
  on /^hello/ do
@@ -49,7 +51,9 @@ class MyCompanyBot < Hipbot::Bot
49
51
  end
50
52
  end
51
53
 
52
- class PluginClass < Hipbot::Plugin
54
+ class PluginClass
55
+ include Hipbot::Plugin
56
+
53
57
  on /^plugin/ do
54
58
  reply('this is from plugin!')
55
59
  end
@@ -60,7 +64,7 @@ MyCompanyBot.start!
60
64
 
61
65
  You can create a response by providing simple regexp:
62
66
 
63
- ``` ruby
67
+ ```ruby
64
68
  on /^hello/ do
65
69
  reply('hello!')
66
70
  end
@@ -68,7 +72,7 @@ end
68
72
 
69
73
  Responses can pass arguments from regexps:
70
74
 
71
- ``` ruby
75
+ ```ruby
72
76
  on /my name is (.*)/ do |user_name|
73
77
  reply('hello #{user_name}!')
74
78
  end
@@ -76,7 +80,7 @@ end
76
80
 
77
81
  Define multiple regexps for a response:
78
82
 
79
- ``` ruby
83
+ ```ruby
80
84
  on /my name is (.*)/, /I am (.*)/ do |name|
81
85
  reply('hello #{user_name}!')
82
86
  end
@@ -84,7 +88,7 @@ end
84
88
 
85
89
  Use :from to only match messages from certain users or user groups defined in configuration
86
90
 
87
- ``` ruby
91
+ ```ruby
88
92
  configure do |c|
89
93
  # ...
90
94
  c.teams = { vip: ['John', 'Mike'] }
@@ -97,7 +101,7 @@ end
97
101
 
98
102
  Use :room to only match messages in certain hipchat rooms
99
103
 
100
- ``` ruby
104
+ ```ruby
101
105
  configure do |c|
102
106
  # ...
103
107
  c.rooms = { project_rooms: ['Project 1', 'Project 2'] }
@@ -110,7 +114,7 @@ end
110
114
 
111
115
  Use :global to react to messages that are not sent directly to @robot
112
116
 
113
- ``` ruby
117
+ ```ruby
114
118
  on /hey I just met you/, global: true do
115
119
  reply('and this is crazy...')
116
120
  end
@@ -124,7 +128,7 @@ For more examples, check out (https://github.com/pewniak747/hipbot/tree/master/e
124
128
 
125
129
  Use http helpers (`get`, `post`, `put`, `delete`) to preform a http request:
126
130
 
127
- ``` ruby
131
+ ```ruby
128
132
  on /curl (\S+)/ do |url|
129
133
  get url do |response|
130
134
  reply(response.code)
@@ -134,7 +138,7 @@ on /curl (\S+)/ do |url|
134
138
  end
135
139
  ```
136
140
 
137
- ``` ruby
141
+ ```ruby
138
142
  on /ping site/ do
139
143
  get 'http://example.com', ping: "1" # issues http://example.com?ping=1
140
144
  end
@@ -149,7 +153,7 @@ Inside response you have access to following variables:
149
153
 
150
154
  You can define your own helpers and use them inside responses like this:
151
155
 
152
- ``` ruby
156
+ ```ruby
153
157
  module HipbotHelpers
154
158
  def project_name
155
159
  "#{room.name}-project"
@@ -170,10 +174,11 @@ end
170
174
 
171
175
  #### Plugins
172
176
 
173
- To define a plugin, subclass `Hipbot::Plugin` and add responses like in bot:
177
+ To define a plugin, include `Hipbot::Plugin` and add responses like in bot:
174
178
 
175
- ``` ruby
176
- class GreeterPlugin < Hipbot::Plugin
179
+ ```ruby
180
+ class GreeterPlugin
181
+ include Hipbot::Plugin
177
182
  on /^hello/ do
178
183
  reply('hello there!')
179
184
  end
@@ -182,12 +187,11 @@ end
182
187
 
183
188
  You can gain access to plugin data inside reaction with `plugin` helper:
184
189
 
185
- ``` ruby
186
- class GreeterPlugin < Hipbot::Plugin
190
+ ```ruby
191
+ class GreeterPlugin
192
+ include Hipbot::Plugin
193
+
187
194
  attr_accessor :language
188
- def initialize(language)
189
- self.language = language
190
- end
191
195
 
192
196
  on /^hello/ do
193
197
  case plugin.language
@@ -200,6 +204,10 @@ class GreeterPlugin < Hipbot::Plugin
200
204
  end
201
205
  end
202
206
  end
207
+
208
+ GreeterPlugin.configure do |c|
209
+ c.language = :jp
210
+ end
203
211
  ```
204
212
 
205
213
  For a collection of open-source plugins, see https://github.com/netguru/hipbot-plugins
@@ -2,8 +2,8 @@
2
2
  require File.expand_path('../lib/hipbot/version', __FILE__)
3
3
 
4
4
  Gem::Specification.new do |gem|
5
- gem.authors = ["Tomasz Pewiński"]
6
- gem.email = ["pewniak747@gmail.com"]
5
+ gem.authors = ["Bartosz Kopiński", "Tomasz Pewiński"]
6
+ gem.email = ["bartosz.kopinski@netguru.pl", "pewniak747@gmail.com"]
7
7
  gem.description = "Hipbot is a bot for HipChat, written in ruby & eventmachine."
8
8
  gem.summary = "Hipbot is a bot for HipChat, written in ruby & eventmachine."
9
9
  gem.homepage = "http://github.com/pewniak747/hipbot"
@@ -19,6 +19,7 @@ require 'hipbot/plugin'
19
19
  require 'hipbot/configuration'
20
20
  require 'hipbot/collection'
21
21
  require 'hipbot/helpers'
22
+ require 'hipbot/match'
22
23
  require 'hipbot/message'
23
24
  require 'hipbot/reaction'
24
25
  require 'hipbot/response'
@@ -2,10 +2,8 @@ module Hipbot
2
2
  module Adapters
3
3
  module Hipchat
4
4
  class Connection
5
- def initialize bot
6
- @bot = bot
7
- @bot.connection = self
8
-
5
+ def initialize
6
+ Hipbot.connection = self
9
7
  setup_error_handler && setup_bot && setup_timers
10
8
  end
11
9
 
@@ -15,71 +13,78 @@ module Hipbot
15
13
  end
16
14
 
17
15
  def send_to_room(room, message)
16
+ Hipbot.logger.info("REPLY in #{room}: #{message}")
18
17
  @client.send_message(:groupchat, room.id, message)
19
18
  end
20
19
 
21
20
  def send_to_user(user, message)
21
+ Hipbot.logger.info("REPLY to #{user}: #{message}")
22
22
  @client.send_message(:chat, user.id, message)
23
23
  end
24
24
 
25
25
  def set_topic(room, topic)
26
+ Hipbot.logger.info("TOPIC set in #{room} to '#{topic}'")
26
27
  @client.send_message(:groupchat, room.id, nil, topic)
27
28
  end
28
29
 
29
30
  def set_presence(status = nil, type = :available)
31
+ Hipbot.logger.info("PRESENCE set to #{type} with '#{status}'")
30
32
  @client.set_presence(type, nil, status)
31
33
  end
32
34
 
33
- private
35
+ protected
34
36
 
35
37
  def setup_bot
36
38
  initialize_client do
37
39
  initialize_rooms
38
40
  initialize_users
39
41
  initialize_callbacks
42
+ set_bot_user
40
43
  join_rooms
41
44
  set_presence('Hello humans!')
42
45
  end
43
46
  end
44
47
 
45
48
  def initialize_client
46
- @client = ::Jabber::MUC::HipchatClient.new(@bot.jid + '/' + @bot.name)
47
- yield if @client.connect(@bot.password)
49
+ @client = ::Jabber::MUC::HipchatClient.new(Hipbot.jid)
50
+ yield if @client.connect(Hipbot.password)
48
51
  end
49
52
 
50
53
  def initialize_rooms
51
- @client.get_rooms.each do |r|
52
- Room.create(r[:item].jid, r[:item].iname, topic: r[:details]['topic'])
54
+ @client.get_rooms.each do |room_data|
55
+ room = Room.find_or_create_by(id: room_data[:item].jid.to_s)
56
+ room.update_attributes({
57
+ name: room_data[:item].iname,
58
+ topic: room_data[:details]['topic'],
59
+ })
53
60
  end
54
- true
55
61
  end
56
62
 
57
63
  def initialize_users
58
- @client.get_users.each do |v|
59
- params = {
60
- email: v[:vcard]['EMAIL/USERID'],
61
- mention: v[:item].attributes['mention_name'],
62
- title: v[:vcard]['TITLE'],
63
- photo: v[:vcard]['PHOTO'],
64
- }
65
- User.create(v[:item].jid, v[:item].iname, params)
64
+ @client.get_users.each do |user_data|
65
+ user = User.find_or_create_by(id: user_data.delete(:jid))
66
+ user.update_attributes(user_data)
67
+
68
+ if user.attributes['email'].nil?
69
+ user.update_attributes(@client.get_user_details(user.id))
70
+ end
66
71
  end
67
- true
72
+ end
73
+
74
+ def set_bot_user
75
+ Hipbot.configuration.user = User[Hipbot.jid]
76
+ @client.name = Hipbot.user
68
77
  end
69
78
 
70
79
  def join_rooms
71
- with_rooms do |rooms|
72
- rooms.each do |r|
73
- @client.join(r.id)
74
- end
80
+ with_rooms do |room|
81
+ @client.join(room.id)
75
82
  end
76
83
  end
77
84
 
78
85
  def exit_all_rooms
79
- with_rooms do |rooms|
80
- rooms.each do |r|
81
- @client.exit(r.id, 'bye bye!')
82
- end
86
+ with_rooms do |room|
87
+ @client.exit(room.id, 'bye bye!')
83
88
  end
84
89
  end
85
90
 
@@ -93,40 +98,40 @@ module Hipbot
93
98
 
94
99
  def message_callback room_jid, user_name, message
95
100
  with_sender(room_jid, user_name) do |room, user|
96
- room.params.topic = message.subject if message.subject.present?
97
- return if user_name == @bot.name || message.body.blank?
98
- @bot.react(user, room, message.body)
101
+ room.update_attribute(:topic, message.subject) if message.subject.present?
102
+ return if user_name == Hipbot.name || message.body.blank?
103
+ Hipbot.react(user, room, message.body)
99
104
  end
100
105
  end
101
106
 
102
107
  def invite_callback room_jid, user_name, room_name, topic
103
- Room.create(room_jid, room_name, topic: topic)
108
+ Room.create(id: room_jid, name: room_name, topic: topic)
104
109
  @client.join(room_jid)
105
110
  end
106
111
 
107
112
  def presence_callback room_jid, user_name, pres
108
113
  with_sender(room_jid, user_name) do |room, user|
109
114
  if pres == 'unavailable'
110
- if user_name == @bot.name
115
+ if user_name == Hipbot.name
111
116
  room.delete
112
117
  elsif user.present?
113
- room.user_ids.delete(user.id)
118
+ room.users.delete(user)
114
119
  end
115
- elsif pres.blank? && room.user_ids.exclude?(user.id)
116
- room.user_ids << user.id
120
+ elsif pres.blank? && room.users.exclude?(user)
121
+ room.users << user
117
122
  end
118
123
  end
119
124
  end
120
125
 
121
126
  def private_message_callback user_jid, message
122
127
  with_user(user_jid) do |user|
123
- @bot.react(user, nil, message.body) if user.name != @bot.name
128
+ Hipbot.react(user, nil, message.body) if user.name != Hipbot.name
124
129
  end if message.body.present?
125
130
  end
126
131
 
127
132
  def with_rooms
128
- return Jabber::debuglog 'No rooms found' if Room.empty?
129
- yield Room
133
+ return Hipbot.logger.error 'No rooms found' if Room.empty?
134
+ Room.each{ |room| yield room }
130
135
  end
131
136
 
132
137
  def with_sender room_id, user_id
@@ -143,15 +148,15 @@ module Hipbot
143
148
 
144
149
  def setup_timers
145
150
  ::EM::add_periodic_timer(60) do
146
- @client.keep_alive(@bot.password) if @client.present?
151
+ @client.keep_alive(Hipbot.password) if @client.present?
147
152
  end
148
153
  end
149
154
 
150
155
  def setup_error_handler
151
156
  ::EM.error_handler do |e|
152
- Jabber::debuglog e.inspect
157
+ Hipbot.logger.error e.inspect
153
158
  e.backtrace.each do |line|
154
- Jabber::debuglog line
159
+ Hipbot.logger.error line
155
160
  end
156
161
  end
157
162
  end
@@ -2,7 +2,7 @@ module Hipbot
2
2
  module Adapters
3
3
  module Hipchat
4
4
  def start!
5
- connection = Connection.new(self)
5
+ connection = Connection.new
6
6
  end
7
7
 
8
8
  def method_missing(sym, *args, &block)
@@ -2,14 +2,13 @@ module Hipbot
2
2
  module Adapters
3
3
  module Telnet
4
4
  class Connection < EM::Connection
5
- def initialize bot
6
- @bot = bot
7
- @bot.connection = self
5
+ def initialize
6
+ Hipbot.connection = self
8
7
  end
9
8
 
10
9
  def receive_data(data)
11
- sender, room, message = *data.strip.split(':')
12
- @bot.react(sender, room, message)
10
+ sender, room, message = data.strip.split(':')
11
+ Hipbot.react(sender, room, message)
13
12
  end
14
13
  end
15
14
  end