robut 0.3.0 → 0.4.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.
- data/.travis.yml +11 -0
- data/Gemfile +2 -3
- data/README.rdoc +38 -19
- data/examples/Chatfile +10 -4
- data/lib/robut.rb +3 -0
- data/lib/robut/connection.rb +10 -72
- data/lib/robut/plugin.rb +94 -13
- data/lib/robut/plugin/echo.rb +3 -13
- data/lib/robut/plugin/google_images.rb +17 -0
- data/lib/robut/plugin/help.rb +7 -15
- data/lib/robut/plugin/meme.rb +22 -53
- data/lib/robut/plugin/pick.rb +18 -0
- data/lib/robut/plugin/ping.rb +3 -9
- data/lib/robut/plugin/quips.rb +60 -0
- data/lib/robut/plugin/say.rb +6 -12
- data/lib/robut/plugin/stock.rb +45 -0
- data/lib/robut/pm.rb +40 -0
- data/lib/robut/presence.rb +35 -0
- data/lib/robut/room.rb +30 -0
- data/lib/robut/version.rb +1 -1
- data/test/mocks/connection_mock.rb +2 -18
- data/test/mocks/presence_mock.rb +25 -0
- data/test/test_helper.rb +3 -1
- data/test/unit/connection_test.rb +58 -25
- data/test/unit/plugin/alias_test.rb +5 -4
- data/test/unit/plugin/echo_test.rb +5 -4
- data/test/unit/plugin/help_test.rb +4 -3
- data/test/unit/plugin/later_test.rb +7 -6
- data/test/unit/plugin/lunch_test.rb +6 -5
- data/test/unit/plugin/pick_test.rb +35 -0
- data/test/unit/plugin/ping_test.rb +4 -3
- data/test/unit/plugin/quips_test.rb +58 -0
- data/test/unit/plugin/say_test.rb +4 -3
- data/test/unit/plugin/weather_test.rb +15 -14
- data/test/unit/plugin_test.rb +62 -1
- data/test/unit/room_test.rb +51 -0
- metadata +28 -20
- data/lib/robut/plugin/rdio.rb +0 -96
- data/lib/robut/plugin/rdio/public/css/rdio.css +0 -141
- data/lib/robut/plugin/rdio/public/css/style.css +0 -79
- data/lib/robut/plugin/rdio/public/css/style_after.css +0 -42
- data/lib/robut/plugin/rdio/public/images/background.png +0 -0
- data/lib/robut/plugin/rdio/public/images/no-album.png +0 -0
- data/lib/robut/plugin/rdio/public/index.html +0 -43
- data/lib/robut/plugin/rdio/public/js/libs/dd_belatedpng.js +0 -13
- data/lib/robut/plugin/rdio/public/js/libs/jquery-1.5.1.min.js +0 -16
- data/lib/robut/plugin/rdio/public/js/libs/modernizr-1.7.min.js +0 -2
- data/lib/robut/plugin/rdio/public/js/rdio.js +0 -129
- data/lib/robut/plugin/rdio/public/js/script.js +0 -3
- data/lib/robut/plugin/rdio/server.rb +0 -57
data/.travis.yml
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
language: ruby
|
2
|
+
rvm:
|
3
|
+
# - 1.8.7
|
4
|
+
- 1.9.2
|
5
|
+
- 1.9.3
|
6
|
+
# - jruby-18mode # JRuby in 1.8 mode
|
7
|
+
# - jruby-19mode # JRuby in 1.9 mode
|
8
|
+
# - rbx-18mode
|
9
|
+
# - rbx-19mode # currently in active development, may or may not work for your project
|
10
|
+
# uncomment this line if your project needs to run something other than `rake`:
|
11
|
+
# script: bundle exec rspec spec
|
data/Gemfile
CHANGED
@@ -8,13 +8,12 @@ group :test do
|
|
8
8
|
gem 'simplecov'
|
9
9
|
gem 'webmock'
|
10
10
|
gem 'time-warp'
|
11
|
+
gem 'mocha'
|
11
12
|
end
|
12
13
|
|
13
14
|
group :plugin do
|
14
15
|
gem 'calc'
|
15
16
|
gem 'twss'
|
16
|
-
gem 'rdio', '0.0.91' # .92 is horked
|
17
|
-
gem 'sinatra'
|
18
17
|
gem 'meme_generator'
|
19
18
|
gem 'nokogiri'
|
20
|
-
end
|
19
|
+
end
|
data/README.rdoc
CHANGED
@@ -1,6 +1,16 @@
|
|
1
1
|
= Robut
|
2
2
|
|
3
|
-
The friendly plugin-enabled HipChat bot.
|
3
|
+
The friendly plugin-enabled HipChat bot.
|
4
|
+
|
5
|
+
== NOTE: Breaking backwards compatibility!
|
6
|
+
|
7
|
+
A little while ago, HipChat changed the way their mention names
|
8
|
+
work. Instead of just using the first name ('@robut'), they now use
|
9
|
+
the full name ('@RobutTRobot'). Starting from v0.4.0, robut uses this
|
10
|
+
new format by default. If you prefer the old style, you can set it in
|
11
|
+
your Chatfile:
|
12
|
+
|
13
|
+
config.mention_name = 'robut'
|
4
14
|
|
5
15
|
== Installation and usage
|
6
16
|
|
@@ -22,8 +32,11 @@ Some of the included plugins require extra gems to be installed:
|
|
22
32
|
|
23
33
|
[Robut::Plugin::TWSS] requires the <tt>twss</tt> gem.
|
24
34
|
[Robut::Plugin::Calc] requires the <tt>calc</tt> gem.
|
25
|
-
[Robut::Plugin::Rdio] requires the <tt>rdio</tt> and <tt>sinatra</tt> gems.
|
26
35
|
[Robut::Plugin::Weather] requires the <tt>nokogiri</tt> gem.
|
36
|
+
[Robut::Plugin::GoogleImages] requires the <tt>google-search</tt> gem.
|
37
|
+
|
38
|
+
A list of known 3rd-party plugins is available on the wiki: https://github.com/justinweiss/robut/wiki/Robut-Plugins
|
39
|
+
Feel free to add your own creations!
|
27
40
|
|
28
41
|
== The Chatfile
|
29
42
|
|
@@ -53,7 +66,7 @@ kind of configuration they support.
|
|
53
66
|
Some plugins might require storage (like the `lunch` plugin). You can
|
54
67
|
configure the type of storage you want to use based on the need for
|
55
68
|
persistence. The default is the HashStore which is in-memory only. Below
|
56
|
-
is an example of using the YamlStore.
|
69
|
+
is an example of using the YamlStore.
|
57
70
|
|
58
71
|
Robut::Connection.configure do |config|
|
59
72
|
# ...
|
@@ -71,13 +84,16 @@ Robut::Connection.configure block:
|
|
71
84
|
Robut::Connection.configure do |config|
|
72
85
|
config.jid = '...@chat.hipchat.com/bot'
|
73
86
|
config.password = 'password'
|
74
|
-
config.nick = '
|
75
|
-
config.
|
76
|
-
|
87
|
+
config.nick = 'Bot Nick'
|
88
|
+
config.rooms = ['1234_room_1@conf.hipchat.com', '1234_room_2@conf.hipchat.com']
|
89
|
+
|
90
|
+
# Custom @mention name
|
91
|
+
config.mention_name = 'Bot'
|
92
|
+
|
77
93
|
# Example of the YamlStore which uses a yaml file for persistence
|
78
94
|
Robut::Storage::YamlStore.file = "~/.robut_store"
|
79
95
|
config.store = Robut::Storage::YamlStore
|
80
|
-
|
96
|
+
|
81
97
|
# Add a logger if you want to debug the connection
|
82
98
|
# config.logger = Logger.new(STDOUT)
|
83
99
|
end
|
@@ -98,16 +114,19 @@ Robut includes a few plugins that we've found useful:
|
|
98
114
|
@robut lunch? # => "Banh Mi!"
|
99
115
|
|
100
116
|
|
101
|
-
[Robut::Plugin::Meme]
|
117
|
+
[Robut::Plugin::Meme] generates meme images using memecaptain.
|
102
118
|
|
103
119
|
@robut meme all_the_things drink; all the beer
|
104
120
|
|
121
|
+
[Robut::Plugin::GoogleImages] does a google image search for a query and returns the first result.
|
105
122
|
|
106
|
-
|
123
|
+
@robut image ship it
|
124
|
+
|
125
|
+
[Robut::Plugin::Sayings] a simple regex listener and responder.
|
107
126
|
|
108
127
|
You're the worst robot ever, @robut. # => I know.
|
109
128
|
|
110
|
-
[Robut::Plugin::TWSS] an interface to the TWSS gem. Listens to anything said in the chat room and responds "That's what she said!" where appropriate.
|
129
|
+
[Robut::Plugin::TWSS] an interface to the TWSS gem. Listens to anything said in the chat room and responds "That's what she said!" where appropriate.
|
111
130
|
|
112
131
|
well hurry up, you're not going fast enough # => "That's what she said!"
|
113
132
|
|
@@ -117,12 +136,12 @@ Robut includes a few plugins that we've found useful:
|
|
117
136
|
@robut echo hello world # => "hello world"
|
118
137
|
|
119
138
|
|
120
|
-
[Robut::Plugin::Say] invokes the "say" command (text-to-speech).
|
139
|
+
[Robut::Plugin::Say] invokes the "say" command (text-to-speech).
|
121
140
|
|
122
141
|
@robut say this rocks # (make sure robut is running on a machine with speakers :)
|
123
142
|
|
124
143
|
|
125
|
-
[Robut::Plugin::Ping] responds with "pong".
|
144
|
+
[Robut::Plugin::Ping] responds with "pong".
|
126
145
|
|
127
146
|
@robut ping # => "pong"
|
128
147
|
|
@@ -132,11 +151,6 @@ Robut includes a few plugins that we've found useful:
|
|
132
151
|
@robut in 5 minutes echo @justin wake up! # => (5 minutes later) "@justin wake up!"
|
133
152
|
|
134
153
|
|
135
|
-
[Robut::Plugin::Rdio] uses the Rdio[http://www.rdio.com] API and a simple web server to queue and play songs on Rdio.
|
136
|
-
|
137
|
-
@robut play ok computer
|
138
|
-
|
139
|
-
|
140
154
|
[Robut::Plugin::Weather] uses Google Weather to fetch for the weather for a given location and day.
|
141
155
|
|
142
156
|
@robut seattle weather saturday? # => "Forecast for Seattle, WA on Sat: Sunny, High: 77F, Low: 55F"
|
@@ -146,6 +160,12 @@ Robut includes a few plugins that we've found useful:
|
|
146
160
|
@robut alias "cowboy" "@robut play bon jovi wanted dead or alive" # Cuz somtimes you need it.
|
147
161
|
@robut alias w weather? # less typing for common stuff
|
148
162
|
|
163
|
+
[Robut::Plugin::Quips] stores and posts Bugzilla-style quips.
|
164
|
+
|
165
|
+
@robut add quip It was great when I wrote it!
|
166
|
+
@robut quip # => It was great when I wrote it!
|
167
|
+
@robut remove quip It was great when I wrote it!
|
168
|
+
|
149
169
|
[Robut::Plugin::Help] lists usage for all the plugins loaded into robut
|
150
170
|
|
151
171
|
@robut help # => command usage
|
@@ -179,5 +199,4 @@ Once your changes are ready:
|
|
179
199
|
|
180
200
|
== Todo
|
181
201
|
|
182
|
-
*
|
183
|
-
* More plugins!
|
202
|
+
* More plugins!
|
data/examples/Chatfile
CHANGED
@@ -8,15 +8,21 @@ Robut::Plugin.plugins << Robut::Plugin::TWSS
|
|
8
8
|
|
9
9
|
# Configure the robut jabber connection and you're good to go!
|
10
10
|
Robut::Connection.configure do |config|
|
11
|
+
# Note that the jid must end with /bot if you don't want robut to
|
12
|
+
# spam the channel, as described by the last bullet point on this
|
13
|
+
# page: https://www.hipchat.com/help/category/xmpp
|
11
14
|
config.jid = '...@chat.hipchat.com/bot'
|
12
15
|
config.password = 'password'
|
13
|
-
config.nick = '
|
16
|
+
config.nick = 'Bot Nick'
|
14
17
|
config.room = '...@conf.hipchat.com'
|
15
|
-
|
18
|
+
|
19
|
+
# Custom @mention name
|
20
|
+
# config.mention_name = 'Bot'
|
21
|
+
|
16
22
|
# Some plugins require storage
|
17
23
|
Robut::Storage::YamlStore.file = ".robut"
|
18
24
|
config.store = Robut::Storage::YamlStore
|
19
|
-
|
25
|
+
|
20
26
|
# Add a logger if you want to debug the connection
|
21
27
|
# config.logger = Logger.new(STDOUT)
|
22
|
-
end
|
28
|
+
end
|
data/lib/robut.rb
CHANGED
data/lib/robut/connection.rb
CHANGED
@@ -19,7 +19,7 @@ class Robut::Connection
|
|
19
19
|
# [+jid+, +password+, +nick+] The HipChat credentials given on
|
20
20
|
# https://www.hipchat.com/account/xmpp
|
21
21
|
#
|
22
|
-
# [+
|
22
|
+
# [+rooms+] The chat room(s) to join, with each in the format <tt>jabber_name</tt>@<tt>conference_server</tt>
|
23
23
|
#
|
24
24
|
# [+logger+] a logger instance to use for debug output.
|
25
25
|
attr_accessor :config
|
@@ -27,15 +27,15 @@ class Robut::Connection
|
|
27
27
|
# The Jabber::Client that's connected to the HipChat server.
|
28
28
|
attr_accessor :client
|
29
29
|
|
30
|
-
# The MUC that wraps the Jabber Chat protocol.
|
31
|
-
attr_accessor :muc
|
32
|
-
|
33
30
|
# The storage instance that's available to plugins
|
34
31
|
attr_accessor :store
|
35
32
|
|
36
33
|
# The roster of currently available people
|
37
34
|
attr_accessor :roster
|
38
35
|
|
36
|
+
# The rooms that robut is connected to.
|
37
|
+
attr_accessor :rooms
|
38
|
+
|
39
39
|
class << self
|
40
40
|
# Class-level config. This is set by the +configure+ class method,
|
41
41
|
# and is used if no configuration is passed to the +initialize+
|
@@ -65,8 +65,8 @@ class Robut::Connection
|
|
65
65
|
self.config = _config || self.class.config
|
66
66
|
|
67
67
|
self.client = Jabber::Client.new(self.config.jid)
|
68
|
-
self.muc = Jabber::MUC::SimpleMUCClient.new(client)
|
69
68
|
self.store = self.config.store || Robut::Storage::HashStore # default to in-memory store only
|
69
|
+
self.config.rooms ||= Array(self.config.room) # legacy support?
|
70
70
|
|
71
71
|
if self.config.logger
|
72
72
|
Jabber.logger = self.config.logger
|
@@ -74,43 +74,6 @@ class Robut::Connection
|
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
77
|
-
# Send +message+ to the room we're currently connected to, or
|
78
|
-
# directly to the person referenced by +to+. +to+ can be either a
|
79
|
-
# jid or the string name of the person.
|
80
|
-
def reply(message, to = nil)
|
81
|
-
if to
|
82
|
-
unless to.kind_of?(Jabber::JID)
|
83
|
-
to = find_jid_by_name(to)
|
84
|
-
end
|
85
|
-
|
86
|
-
msg = Jabber::Message.new(to || muc.room, message)
|
87
|
-
msg.type = :chat
|
88
|
-
client.send(msg)
|
89
|
-
else
|
90
|
-
muc.send(Jabber::Message.new(muc.room, message))
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
# Sends the chat message +message+ through +plugins+.
|
95
|
-
def handle_message(plugins, time, nick, message)
|
96
|
-
# ignore all messages sent by robut. If you really want robut to
|
97
|
-
# reply to itself, you can use +fake_message+.
|
98
|
-
return if nick == config.nick
|
99
|
-
|
100
|
-
plugins.each do |plugin|
|
101
|
-
begin
|
102
|
-
rsp = plugin.handle(time, nick, message)
|
103
|
-
break if rsp == true
|
104
|
-
rescue => e
|
105
|
-
reply("UH OH! #{plugin.class.name} just crashed!")
|
106
|
-
if config.logger
|
107
|
-
config.logger.error e
|
108
|
-
config.logger.error e.backtrace.join("\n")
|
109
|
-
end
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
77
|
# Connects to the specified room with the given credentials, and
|
115
78
|
# enters an infinite loop. Any messages sent to the room will pass
|
116
79
|
# through all the included plugins.
|
@@ -122,36 +85,17 @@ class Robut::Connection
|
|
122
85
|
self.roster = Jabber::Roster::Helper.new(client)
|
123
86
|
roster.wait_for_roster
|
124
87
|
|
125
|
-
|
126
|
-
|
127
|
-
plugins = Robut::Plugin.plugins.map { |p| p.new(self, nil) }
|
128
|
-
handle_message(plugins, time, nick, message)
|
129
|
-
end
|
130
|
-
|
131
|
-
# Add the callback from direct messages. Turns out the
|
132
|
-
# on_private_message callback doesn't do what it sounds like, so I
|
133
|
-
# have to go a little deeper into xmpp4r to get this working.
|
134
|
-
client.add_message_callback(200, self) do |message|
|
135
|
-
if !muc.from_room?(message.from) && message.type == :chat && message.body
|
136
|
-
time = Time.now # TODO: get real timestamp? Doesn't seem like
|
137
|
-
# jabber gives it to us
|
138
|
-
sender_jid = message.from
|
139
|
-
plugins = Robut::Plugin.plugins.map { |p| p.new(self, sender_jid) }
|
140
|
-
handle_message(plugins, time, self.roster[sender_jid].iname, message.body)
|
141
|
-
true
|
142
|
-
else
|
143
|
-
false
|
144
|
-
end
|
88
|
+
rooms = self.config.rooms.collect do |room_name|
|
89
|
+
Robut::Room.new(self, room_name).tap {|r| r.join }
|
145
90
|
end
|
146
91
|
|
147
|
-
|
92
|
+
personal_message = Robut::PM.new(self, rooms)
|
148
93
|
|
149
94
|
trap_signals
|
150
95
|
loop { sleep 1 }
|
151
96
|
end
|
152
97
|
|
153
|
-
|
154
|
-
|
98
|
+
private
|
155
99
|
# Since we're entering an infinite loop, we have to trap TERM and
|
156
100
|
# INT. If something like the Rdio plugin has started a server that
|
157
101
|
# has already trapped those signals, we want to run those signal
|
@@ -167,10 +111,4 @@ class Robut::Connection
|
|
167
111
|
old_signal_callbacks[sig] = trap(sig) { signal_callback.call(sig) }
|
168
112
|
end
|
169
113
|
end
|
170
|
-
|
171
|
-
# Find a jid in the roster with the given name, case-insensitively
|
172
|
-
def find_jid_by_name(name)
|
173
|
-
name = name.downcase
|
174
|
-
roster.items.detect {|jid, item| item.iname.downcase == name}.first
|
175
|
-
end
|
176
|
-
end
|
114
|
+
end
|
data/lib/robut/plugin.rb
CHANGED
@@ -3,6 +3,45 @@
|
|
3
3
|
# module.
|
4
4
|
module Robut::Plugin
|
5
5
|
|
6
|
+
# Contains methods that will be added directly to a class including
|
7
|
+
# Robut::Plugin.
|
8
|
+
module ClassMethods
|
9
|
+
|
10
|
+
# Sets up a 'matcher' that will try to match input being sent to
|
11
|
+
# this plugin with a regular expression. If the expression
|
12
|
+
# matches, +action+ will be performed. +action+ will be passed any
|
13
|
+
# captured groups in the regular expression as parameters. For
|
14
|
+
# example:
|
15
|
+
#
|
16
|
+
# match /^say hello to (\w+)/ do |name| ...
|
17
|
+
#
|
18
|
+
# The action is run in the context of an instance of a class that
|
19
|
+
# includes Robut::Plugin. Like +handle+, an action explicitly
|
20
|
+
# returning +true+ will stop the plugin chain from matching any
|
21
|
+
# further.
|
22
|
+
#
|
23
|
+
# Supported options:
|
24
|
+
# :sent_to_me - only try to match this regexp if it contains an @reply to robut.
|
25
|
+
# This will also strip the @reply from the message we're trying
|
26
|
+
# to match on, so ^ and $ will still do the right thing.
|
27
|
+
def match(regexp, options = {}, &action)
|
28
|
+
matchers << [regexp, options, action, @last_description]
|
29
|
+
@last_description = nil
|
30
|
+
end
|
31
|
+
|
32
|
+
# Provides a description for the next matcher
|
33
|
+
def desc(string)
|
34
|
+
@last_description = string
|
35
|
+
end
|
36
|
+
|
37
|
+
# A list of regular expressions to apply to input being sent to
|
38
|
+
# the plugin, along with blocks of actions to perform. Each
|
39
|
+
# element is a [regexp, options, action, description] array.
|
40
|
+
def matchers
|
41
|
+
@matchers ||= []
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
6
45
|
class << self
|
7
46
|
# A list of all available plugin classes. When you require a new
|
8
47
|
# plugin class, you should add it to this list if you want it to
|
@@ -21,10 +60,18 @@ module Robut::Plugin
|
|
21
60
|
# room.
|
22
61
|
attr_accessor :private_sender
|
23
62
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
63
|
+
attr_accessor :reply_to
|
64
|
+
|
65
|
+
# :nodoc:
|
66
|
+
def self.included(klass)
|
67
|
+
klass.send(:extend, ClassMethods)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Creates a new instance of this plugin to reply to a particular
|
71
|
+
# object over that object's connection
|
72
|
+
def initialize(reply_to, private_sender = nil)
|
73
|
+
self.reply_to = reply_to
|
74
|
+
self.connection = reply_to.connection
|
28
75
|
self.private_sender = private_sender
|
29
76
|
end
|
30
77
|
|
@@ -33,9 +80,9 @@ module Robut::Plugin
|
|
33
80
|
# original message was sent. Otherwise, PMs the message to +to+.
|
34
81
|
def reply(message, to = nil)
|
35
82
|
if to == :room
|
36
|
-
|
83
|
+
reply_to.reply(message, nil)
|
37
84
|
else
|
38
|
-
|
85
|
+
reply_to.reply(message, to || private_sender)
|
39
86
|
end
|
40
87
|
end
|
41
88
|
|
@@ -44,7 +91,7 @@ module Robut::Plugin
|
|
44
91
|
# stripped out. This is useful to separate the 'parameters' from the
|
45
92
|
# 'commands' in a message.
|
46
93
|
def words(message, command = nil)
|
47
|
-
reply = at_nick
|
94
|
+
reply = at_nick.downcase
|
48
95
|
command = command.downcase if command
|
49
96
|
message.split.reject {|word| word.downcase == reply || word.downcase == command }
|
50
97
|
end
|
@@ -53,7 +100,7 @@ module Robut::Plugin
|
|
53
100
|
# Given "@robut do this thing", Returns "do this thing"
|
54
101
|
def without_nick(message)
|
55
102
|
possible_nick, command = message.split(' ', 2)
|
56
|
-
if possible_nick ==
|
103
|
+
if possible_nick.casecmp(at_nick) == 0
|
57
104
|
command
|
58
105
|
else
|
59
106
|
message
|
@@ -62,12 +109,12 @@ module Robut::Plugin
|
|
62
109
|
|
63
110
|
# The bot's nickname, for @-replies.
|
64
111
|
def nick
|
65
|
-
connection.config.nick.
|
112
|
+
connection.config.mention_name || connection.config.nick.gsub(/[^0-9a-z]/i, '')
|
66
113
|
end
|
67
114
|
|
68
115
|
# #nick with the @-symbol prepended
|
69
116
|
def at_nick
|
70
|
-
"@#{nick
|
117
|
+
"@#{nick}"
|
71
118
|
end
|
72
119
|
|
73
120
|
# Was +message+ sent to Robut as an @reply?
|
@@ -80,22 +127,56 @@ module Robut::Plugin
|
|
80
127
|
# method. Plugins are handled in the order that they appear in
|
81
128
|
# Robut::Plugin.plugins
|
82
129
|
def handle(time, sender_nick, message)
|
83
|
-
|
130
|
+
if matchers.empty?
|
131
|
+
raise NotImplementedError, "Implement me in #{self.class.name}!"
|
132
|
+
else
|
133
|
+
find_match(message)
|
134
|
+
end
|
84
135
|
end
|
85
136
|
|
86
137
|
# Returns a list of messages describing the commands this plugin
|
87
138
|
# handles.
|
88
139
|
def usage
|
140
|
+
matchers.map do |regexp, options, action, description|
|
141
|
+
next unless description
|
142
|
+
if options[:sent_to_me]
|
143
|
+
at_nick + " " + description
|
144
|
+
else
|
145
|
+
description
|
146
|
+
end
|
147
|
+
end.compact
|
89
148
|
end
|
90
149
|
|
91
150
|
def fake_message(time, sender_nick, msg)
|
92
151
|
# TODO: ensure this connection is threadsafe
|
93
|
-
plugins = Robut::Plugin.plugins.map { |p| p.new(
|
94
|
-
|
152
|
+
plugins = Robut::Plugin.plugins.map { |p| p.new(reply_to, private_sender) }
|
153
|
+
reply_to.handle_message(plugins, time, sender_nick, msg)
|
95
154
|
end
|
96
155
|
|
97
156
|
# Accessor for the store instance
|
98
157
|
def store
|
99
158
|
connection.store
|
100
159
|
end
|
160
|
+
|
161
|
+
private
|
162
|
+
|
163
|
+
# Find and run all the actions associated with matchers that match
|
164
|
+
# +message+.
|
165
|
+
def find_match(message)
|
166
|
+
matchers.each do |regexp, options, action, description|
|
167
|
+
if options[:sent_to_me] && !sent_to_me?(message)
|
168
|
+
next
|
169
|
+
end
|
170
|
+
|
171
|
+
if match_data = without_nick(message).match(regexp)
|
172
|
+
# Return true explicitly if this matcher explicitly returned true
|
173
|
+
break true if instance_exec(*match_data[1..-1], &action) == true
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
# The matchers defined by this plugin's class
|
179
|
+
def matchers
|
180
|
+
self.class.matchers
|
181
|
+
end
|
101
182
|
end
|