dog-bot 0.1.0 → 0.1.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.
- data/bin/dog +5 -7
- data/config_examples/default_rooms.rb +1 -0
- data/config_examples/dog.rb +14 -0
- data/config_examples/google_image.rb +11 -0
- data/config_examples/jenkins.rb +41 -0
- data/config_examples/ruby_gems.rb +18 -0
- data/config_examples/tasks.rb +4 -0
- data/config_examples/twitter.rb +10 -0
- data/config_examples/xkcd.rb +12 -0
- data/dog.gemspec +1 -1
- data/lib/dog.rb +1 -1
- data/lib/dog/bot.rb +44 -41
- data/lib/dog/command.rb +17 -15
- data/lib/dog/configure.rb +31 -10
- data/lib/dog/connection.rb +7 -7
- data/lib/dog/scheduled_task.rb +5 -5
- data/lib/dog/scheduler.rb +32 -0
- data/spec/dog/bot_spec.rb +38 -10
- data/spec/dog/configure_spec.rb +32 -6
- data/spec/dog/scheduled_task_spec.rb +1 -1
- metadata +19 -14
- data/dog_config_example.rb +0 -59
- data/lib/dog/brain.rb +0 -15
- data/spec/dog/brain_spec.rb +0 -35
data/bin/dog
CHANGED
@@ -8,19 +8,17 @@ end
|
|
8
8
|
|
9
9
|
user, password, config_path = ARGV
|
10
10
|
|
11
|
-
xmpp_client = Blather::Client.setup
|
12
|
-
xmpp_connection = Dog::Connection.new
|
11
|
+
xmpp_client = Blather::Client.setup(user, password)
|
12
|
+
xmpp_connection = Dog::Connection.new(xmpp_client)
|
13
13
|
|
14
|
-
@bot = Dog::Bot.new
|
14
|
+
@bot = Dog::Bot.new(xmpp_connection, config_path)
|
15
15
|
|
16
16
|
xmpp_client.register_handler(:ready) { @bot.config }
|
17
|
-
xmpp_client.register_handler(:message, :chat?, :body) { |m| @bot.process_chat_message
|
18
|
-
xmpp_client.register_handler(:message, :groupchat?, :body) { |m| @bot.process_group_chat_message
|
17
|
+
xmpp_client.register_handler(:message, :chat?, :body) { |m| @bot.process_chat_message(m) }
|
18
|
+
xmpp_client.register_handler(:message, :groupchat?, :body) { |m| @bot.process_group_chat_message(m) }
|
19
19
|
xmpp_client.register_handler(:disconnected) { xmpp_client.run }
|
20
20
|
xmpp_client.register_handler(:error) { puts "ERROR" }
|
21
21
|
|
22
|
-
Blather.logger.level = Logger::DEBUG
|
23
|
-
|
24
22
|
trap(:INT) { EM.stop }
|
25
23
|
trap(:TERM) { EM.stop }
|
26
24
|
EM.run { xmpp_client.run }
|
@@ -0,0 +1 @@
|
|
1
|
+
chat_rooms "dog_test", "dog_test2"
|
@@ -0,0 +1,41 @@
|
|
1
|
+
task "check failing builds" do |t|
|
2
|
+
t.every "5s"
|
3
|
+
t.action do |bot|
|
4
|
+
json = open("http://127.0.0.1:1337").read
|
5
|
+
ci = JSON.parse(json)
|
6
|
+
old_failing_jons = bot.memory.fetch(:jenkins_failing_builds, [])
|
7
|
+
failing_jobs = ci["jobs"].find_all { |job| job["color"] == "red" }
|
8
|
+
bot.memory[:jenkins_failing_builds] = failing_jobs
|
9
|
+
|
10
|
+
new_failing_jobs = failing_jobs - old_failing_jons
|
11
|
+
|
12
|
+
if new_failing_jobs.any?
|
13
|
+
if new_failing_jobs.count > 1
|
14
|
+
failing_job_names = new_failing_jobs.map { |job| job["name"] }.join(", ")
|
15
|
+
"#{new_failing_jobs.count} new failing builds: #{failing_job_names}"
|
16
|
+
else
|
17
|
+
"#{new_failing_jobs.first["name"]} started failing"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
command "dog" do
|
24
|
+
matches "dog"
|
25
|
+
|
26
|
+
subcommand "jekins" do
|
27
|
+
matches "ci", "jenkins"
|
28
|
+
action do
|
29
|
+
json = open("http://127.0.0.1:1337").read
|
30
|
+
ci = JSON.parse(json)
|
31
|
+
failing_jobs = ci["jobs"].find_all { |job| job["color"] == "red" }
|
32
|
+
|
33
|
+
if failing_jobs.any?
|
34
|
+
failing_job_names = failing_jobs.map { |job| job["name"] }.join(", ")
|
35
|
+
"#{failing_jobs.count} failing builds: #{failing_job_names}"
|
36
|
+
else
|
37
|
+
"no failing builds!"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
command "dog" do
|
2
|
+
matches "dog"
|
3
|
+
|
4
|
+
subcommand "ruby gems" do
|
5
|
+
matches "gem"
|
6
|
+
action do |message|
|
7
|
+
begin
|
8
|
+
gem_name = message.split(" ").last
|
9
|
+
uri = URI.parse "http://rubygems.org/api/v1/gems/#{gem_name}.json"
|
10
|
+
gem = JSON.parse uri.open.read
|
11
|
+
|
12
|
+
"'#{gem["name"]}' version: #{gem["version"]} downloads: #{gem["downloads"]}"
|
13
|
+
rescue
|
14
|
+
"gem not found"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
command "get body of tweet" do
|
2
|
+
matches /twitter\.com/
|
3
|
+
action do |message|
|
4
|
+
id = message.split("/").last
|
5
|
+
uri = URI.parse "https://api.twitter.com/1/statuses/show.json?id=#{id}"
|
6
|
+
tweet = JSON.parse uri.open.read
|
7
|
+
|
8
|
+
"#{tweet["text"]} - @#{tweet["user"]["screen_name"]}"
|
9
|
+
end
|
10
|
+
end
|
data/dog.gemspec
CHANGED
@@ -12,7 +12,7 @@
|
|
12
12
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
13
13
|
gem.name = "dog-bot"
|
14
14
|
gem.require_paths = ["lib"]
|
15
|
-
gem.version = "0.1.
|
15
|
+
gem.version = "0.1.1"
|
16
16
|
|
17
17
|
gem.add_dependency "blather", "~> 0.8.0"
|
18
18
|
gem.add_dependency "google_image_api", "~> 0.0.1"
|
data/lib/dog.rb
CHANGED
data/lib/dog/bot.rb
CHANGED
@@ -1,39 +1,40 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'rufus/scheduler'
|
3
|
-
|
4
1
|
module Dog
|
5
2
|
class Bot
|
6
|
-
|
3
|
+
attr_accessor :memory
|
4
|
+
|
5
|
+
def initialize(connection, config_path)
|
7
6
|
@config_path = config_path
|
8
7
|
@connection = connection
|
9
8
|
@commands = []
|
10
9
|
@rooms = []
|
11
|
-
@
|
10
|
+
@scheduler = Scheduler.new(self)
|
11
|
+
@memory = {}
|
12
12
|
end
|
13
13
|
|
14
|
-
def process_chat_message
|
15
|
-
response = process
|
16
|
-
|
14
|
+
def process_chat_message(message)
|
15
|
+
response = process(message.body)
|
16
|
+
say(message.from, response) unless response.nil?
|
17
17
|
end
|
18
18
|
|
19
|
-
def process_group_chat_message
|
19
|
+
def process_group_chat_message(message)
|
20
20
|
return if _from_self(message) || message.delayed?
|
21
21
|
|
22
22
|
response = process message.body
|
23
|
-
|
23
|
+
|
24
|
+
say_to_chat(message.from.node, response) unless response.nil?
|
24
25
|
end
|
25
26
|
|
26
|
-
def process
|
27
|
-
response = respond_to
|
27
|
+
def process(message)
|
28
|
+
response = respond_to(message)
|
28
29
|
|
29
|
-
if response.is_a?
|
30
|
-
respond_to_action
|
30
|
+
if response.is_a?(Symbol)
|
31
|
+
respond_to_action(message, response)
|
31
32
|
else
|
32
33
|
response
|
33
34
|
end
|
34
35
|
end
|
35
36
|
|
36
|
-
def respond_to
|
37
|
+
def respond_to(text)
|
37
38
|
@commands.each do |command|
|
38
39
|
response = command.respond_to text
|
39
40
|
return response unless response.nil?
|
@@ -42,7 +43,7 @@ module Dog
|
|
42
43
|
nil
|
43
44
|
end
|
44
45
|
|
45
|
-
def respond_to_action
|
46
|
+
def respond_to_action(message, kind)
|
46
47
|
case kind
|
47
48
|
when :join then
|
48
49
|
room_name = message.split.last
|
@@ -51,44 +52,46 @@ module Dog
|
|
51
52
|
when :reload then
|
52
53
|
config
|
53
54
|
"config reloaded"
|
55
|
+
when :run_task
|
56
|
+
title = message.split[3..-1].join(" ")
|
57
|
+
return nil if title.empty?
|
58
|
+
task = @tasks.find { |t| t.title == title }
|
59
|
+
task.run(self) unless task.nil?
|
54
60
|
else "invalid action"
|
55
61
|
end
|
56
62
|
end
|
57
63
|
|
58
|
-
def
|
59
|
-
@connection.
|
60
|
-
@rooms << room_name
|
64
|
+
def say(to, message)
|
65
|
+
@connection.say(to, message)
|
61
66
|
end
|
62
67
|
|
63
|
-
def
|
64
|
-
|
65
|
-
config = Configure.parse config_string
|
66
|
-
|
67
|
-
@commands = config.commands
|
68
|
-
@scheduled_tasks = config.scheduled_tasks
|
69
|
-
|
70
|
-
config.chat_rooms.each { |chat_room| join chat_room }
|
71
|
-
schedule_tasks
|
68
|
+
def say_to_chat(to, message)
|
69
|
+
@connection.say_to_chat(to, message)
|
72
70
|
end
|
73
71
|
|
74
|
-
def
|
75
|
-
@
|
72
|
+
def say_to_all_chat_rooms(message)
|
73
|
+
@rooms.each do |room|
|
74
|
+
say_to_chat(room, message)
|
75
|
+
end
|
76
|
+
end
|
76
77
|
|
77
|
-
|
78
|
+
def join(*room_names)
|
79
|
+
room_names.each do |room_name|
|
80
|
+
@connection.join room_name
|
81
|
+
@rooms << room_name
|
82
|
+
end
|
83
|
+
end
|
78
84
|
|
79
|
-
|
80
|
-
|
81
|
-
response = task.run self
|
82
|
-
next if response.nil?
|
85
|
+
def config
|
86
|
+
config = Configure.parse_path(@config_path)
|
83
87
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
end
|
88
|
+
@commands = config.commands
|
89
|
+
@tasks = config.scheduled_tasks
|
90
|
+
@scheduler.schedule_tasks(@tasks)
|
91
|
+
join(*config.chat_rooms)
|
89
92
|
end
|
90
93
|
|
91
|
-
def _from_self
|
94
|
+
def _from_self(message)
|
92
95
|
@rooms.each do |room|
|
93
96
|
return true if "#{room}@conference.#{@connection.jid.domain}/#{@connection.jid.node}" == message.from
|
94
97
|
end
|
data/lib/dog/command.rb
CHANGED
@@ -1,49 +1,51 @@
|
|
1
1
|
module Dog
|
2
2
|
class Command
|
3
|
-
|
3
|
+
attr_reader :title
|
4
|
+
|
5
|
+
def initialize(title)
|
4
6
|
@title = title
|
5
7
|
@matchers = []
|
6
8
|
@subcommands = []
|
7
|
-
@action = ->
|
9
|
+
@action = ->(input){ }
|
8
10
|
end
|
9
11
|
|
10
|
-
def action
|
12
|
+
def action(&action)
|
11
13
|
@action = action
|
12
14
|
end
|
13
15
|
|
14
|
-
def matches
|
16
|
+
def matches(*matchers)
|
15
17
|
@matchers += matchers
|
16
18
|
end
|
17
19
|
|
18
|
-
def matches?
|
20
|
+
def matches?(input_string)
|
19
21
|
@matchers.any? do |matcher|
|
20
|
-
if matcher.is_a?
|
21
|
-
input_string.match
|
22
|
+
if matcher.is_a?(String)
|
23
|
+
input_string.match(/(\s|^)#{matcher}(\s|$)/)
|
22
24
|
else
|
23
|
-
input_string.match
|
25
|
+
input_string.match(matcher)
|
24
26
|
end
|
25
27
|
end
|
26
28
|
end
|
27
29
|
|
28
|
-
def subcommand
|
30
|
+
def subcommand(title, &block)
|
29
31
|
subcommand = Command.new title
|
30
32
|
subcommand.instance_eval &block
|
31
33
|
@subcommands << subcommand
|
32
34
|
end
|
33
35
|
|
34
|
-
def subcommand_response
|
36
|
+
def subcommand_response(input_string)
|
35
37
|
@subcommands.each do |subcommand|
|
36
|
-
response = subcommand.respond_to
|
38
|
+
response = subcommand.respond_to(input_string)
|
37
39
|
return response unless response.nil?
|
38
40
|
end
|
39
41
|
|
40
42
|
nil
|
41
43
|
end
|
42
44
|
|
43
|
-
def respond_to
|
44
|
-
if matches?
|
45
|
-
|
46
|
-
|
45
|
+
def respond_to(input_string)
|
46
|
+
if matches?(input_string)
|
47
|
+
response = subcommand_response input_string
|
48
|
+
response || @action.call(input_string)
|
47
49
|
end
|
48
50
|
end
|
49
51
|
end
|
data/lib/dog/configure.rb
CHANGED
@@ -3,33 +3,54 @@ require_relative "scheduled_task"
|
|
3
3
|
|
4
4
|
module Dog
|
5
5
|
class Configure
|
6
|
-
def self.
|
6
|
+
def self.parse_path(config_path)
|
7
|
+
parse(_config_string(config_path))
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.parse(config_string)
|
7
11
|
config = Configure.new
|
8
|
-
config.instance_eval
|
12
|
+
config.instance_eval(config_string)
|
9
13
|
config
|
10
14
|
end
|
11
15
|
|
12
|
-
|
16
|
+
def self._config_string(path)
|
17
|
+
return File.read path if File.file? path
|
18
|
+
|
19
|
+
Dir.foreach(path).each_with_object("") do |item, output|
|
20
|
+
next if item == '.' or item == '..'
|
21
|
+
output << _config_string(File.join(path, item))
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
attr_reader :scheduled_tasks, :chat_rooms
|
13
26
|
|
14
27
|
def initialize
|
15
|
-
@commands =
|
28
|
+
@commands = {}
|
16
29
|
@scheduled_tasks = []
|
17
30
|
@chat_rooms = []
|
18
31
|
end
|
19
32
|
|
20
|
-
def
|
21
|
-
|
33
|
+
def commands
|
34
|
+
@commands.values
|
35
|
+
end
|
36
|
+
|
37
|
+
def get_command(command_title)
|
38
|
+
@commands[command_title]
|
39
|
+
end
|
40
|
+
|
41
|
+
def command(title, &block)
|
42
|
+
command = @commands.fetch title, Command.new(title)
|
22
43
|
command.instance_eval &block
|
23
|
-
@commands
|
44
|
+
@commands[title] = command
|
24
45
|
end
|
25
46
|
|
26
|
-
def task
|
27
|
-
task = ScheduledTask.new
|
47
|
+
def task(title)
|
48
|
+
task = ScheduledTask.new(title)
|
28
49
|
yield task
|
29
50
|
@scheduled_tasks << task
|
30
51
|
end
|
31
52
|
|
32
|
-
def chat_rooms
|
53
|
+
def chat_rooms(*chat_rooms)
|
33
54
|
@chat_rooms += chat_rooms
|
34
55
|
end
|
35
56
|
end
|
data/lib/dog/connection.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Dog
|
2
2
|
class Connection
|
3
|
-
def initialize
|
3
|
+
def initialize(client)
|
4
4
|
@client = client
|
5
5
|
end
|
6
6
|
|
@@ -8,23 +8,23 @@ module Dog
|
|
8
8
|
@client.jid
|
9
9
|
end
|
10
10
|
|
11
|
-
def join
|
11
|
+
def join(room_name)
|
12
12
|
room = "#{room_name}@conference.#{jid.domain}"
|
13
13
|
service = jid.node
|
14
14
|
|
15
15
|
join_stanza = Blather::Stanza::Presence::MUC.new
|
16
16
|
join_stanza.to = "#{room}/#{service}"
|
17
17
|
|
18
|
-
@client.write
|
18
|
+
@client.write(join_stanza)
|
19
19
|
end
|
20
20
|
|
21
|
-
def say
|
21
|
+
def say(to, text)
|
22
22
|
@client.write Blather::Stanza::Message.new(to, text, :chat)
|
23
23
|
end
|
24
24
|
|
25
|
-
def say_to_chat
|
26
|
-
to = Blather::JID.new
|
27
|
-
@client.write
|
25
|
+
def say_to_chat(room_name, text)
|
26
|
+
to = Blather::JID.new(room_name, "conference.#{jid.domain}")
|
27
|
+
@client.write(Blather::Stanza::Message.new(to, text, :groupchat))
|
28
28
|
end
|
29
29
|
end
|
30
30
|
end
|
data/lib/dog/scheduled_task.rb
CHANGED
@@ -2,20 +2,20 @@ module Dog
|
|
2
2
|
class ScheduledTask
|
3
3
|
attr_reader :frequency, :title
|
4
4
|
|
5
|
-
def initialize
|
5
|
+
def initialize(title)
|
6
6
|
@title = title
|
7
7
|
end
|
8
8
|
|
9
|
-
def every
|
9
|
+
def every(frequency)
|
10
10
|
@frequency = frequency
|
11
11
|
end
|
12
12
|
|
13
|
-
def action
|
13
|
+
def action(&block)
|
14
14
|
@action = block
|
15
15
|
end
|
16
16
|
|
17
|
-
def run
|
18
|
-
@action.call
|
17
|
+
def run(context)
|
18
|
+
@action.call(context)
|
19
19
|
end
|
20
20
|
end
|
21
21
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rufus/scheduler'
|
3
|
+
|
4
|
+
module Dog
|
5
|
+
class Scheduler
|
6
|
+
def initialize(bot)
|
7
|
+
@bot = bot
|
8
|
+
@scheduler = Rufus::Scheduler.start_new
|
9
|
+
end
|
10
|
+
|
11
|
+
def schedule_tasks(scheduled_tasks)
|
12
|
+
restart
|
13
|
+
|
14
|
+
scheduled_tasks.each do |task|
|
15
|
+
@scheduler.every(task.frequency) do
|
16
|
+
if response = task.run(@bot)
|
17
|
+
@bot.say_to_all_chat_rooms(response)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def restart
|
24
|
+
@scheduler.all_jobs.each do |id, job|
|
25
|
+
job.unschedule
|
26
|
+
end
|
27
|
+
|
28
|
+
@scheduler.stop unless @scheduler.nil?
|
29
|
+
@scheduler = Rufus::Scheduler.start_new
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/spec/dog/bot_spec.rb
CHANGED
@@ -3,8 +3,9 @@ require "minitest/spec"
|
|
3
3
|
require "minitest/autorun"
|
4
4
|
|
5
5
|
require_relative "../../lib/dog/bot"
|
6
|
-
require_relative "../../lib/dog/brain"
|
7
6
|
require_relative "../../lib/dog/command"
|
7
|
+
require_relative "../../lib/dog/scheduler"
|
8
|
+
require_relative "../../lib/dog/scheduled_task"
|
8
9
|
|
9
10
|
class FakeConnection
|
10
11
|
attr_reader :output, :chat_output, :rooms
|
@@ -41,25 +42,32 @@ class Dog::Bot
|
|
41
42
|
command.matches "hi"
|
42
43
|
command.action { "hello" }
|
43
44
|
@commands = [command]
|
45
|
+
|
46
|
+
task = Dog::ScheduledTask.new "my task"
|
47
|
+
task.every "4h"
|
48
|
+
task.action { "I did it!" }
|
49
|
+
@tasks = [task]
|
44
50
|
end
|
45
51
|
end
|
46
52
|
|
47
53
|
describe Dog::Bot do
|
48
54
|
let(:connection) { FakeConnection.new }
|
49
|
-
subject { Dog::Bot.new
|
55
|
+
subject { Dog::Bot.new(connection, "config") }
|
50
56
|
|
51
57
|
before(:each) { subject.config }
|
52
58
|
|
53
59
|
describe ".process_chat_message" do
|
54
60
|
it "processes a message that matches" do
|
55
|
-
message = OpenStruct.new
|
56
|
-
subject.process_chat_message
|
61
|
+
message = OpenStruct.new(:from => "bob", :body => "hi dog")
|
62
|
+
subject.process_chat_message(message)
|
63
|
+
|
57
64
|
connection.output.last.must_equal ["bob", "hello"]
|
58
65
|
end
|
59
66
|
|
60
67
|
it "doesn't process a non-matching message" do
|
61
|
-
message = OpenStruct.new
|
62
|
-
subject.process_chat_message
|
68
|
+
message = OpenStruct.new(:from => "bob", :body => "bad string")
|
69
|
+
subject.process_chat_message(message)
|
70
|
+
|
63
71
|
connection.output.must_be_empty
|
64
72
|
end
|
65
73
|
end
|
@@ -71,7 +79,8 @@ describe Dog::Bot do
|
|
71
79
|
:body => "hi dog",
|
72
80
|
:delayed? => false
|
73
81
|
)
|
74
|
-
subject.process_group_chat_message
|
82
|
+
subject.process_group_chat_message(message)
|
83
|
+
|
75
84
|
connection.chat_output.last.must_equal ["bob", "hello"]
|
76
85
|
end
|
77
86
|
|
@@ -81,21 +90,40 @@ describe Dog::Bot do
|
|
81
90
|
:body => "bad string",
|
82
91
|
:delayed? => false
|
83
92
|
)
|
84
|
-
subject.process_group_chat_message
|
93
|
+
subject.process_group_chat_message(message)
|
85
94
|
connection.chat_output.must_be_empty
|
86
95
|
end
|
87
96
|
end
|
88
97
|
|
89
98
|
describe ".respond_to_action" do
|
90
99
|
it "joins a room" do
|
91
|
-
output = subject.respond_to_action
|
100
|
+
output = subject.respond_to_action("dog join chatroom", :join)
|
101
|
+
|
92
102
|
output.must_equal "joined chatroom"
|
93
103
|
connection.rooms.last.must_equal "chatroom"
|
94
104
|
end
|
95
105
|
|
96
106
|
it "reloads" do
|
97
|
-
output = subject.respond_to_action
|
107
|
+
output = subject.respond_to_action("dog reload", :reload)
|
98
108
|
output.must_equal "config reloaded"
|
99
109
|
end
|
110
|
+
|
111
|
+
it "forces the given task to run" do
|
112
|
+
output = subject.respond_to_action("dog run task my task", :run_task)
|
113
|
+
output.must_equal "I did it!"
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe ".join" do
|
118
|
+
it "joins a room" do
|
119
|
+
subject.join("my_room")
|
120
|
+
connection.rooms.last.must_equal "my_room"
|
121
|
+
end
|
122
|
+
|
123
|
+
it "can join many rooms" do
|
124
|
+
rooms = ["my_room", "my_other_room"]
|
125
|
+
subject.join(*rooms)
|
126
|
+
connection.rooms.must_equal rooms
|
127
|
+
end
|
100
128
|
end
|
101
129
|
end
|
data/spec/dog/configure_spec.rb
CHANGED
@@ -15,6 +15,24 @@ command "greet" do
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
+
command "dog" do
|
19
|
+
matches "dog"
|
20
|
+
|
21
|
+
subcommand "pet" do
|
22
|
+
matches "pet"
|
23
|
+
action { "*wags tail*" }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
command "dog" do
|
28
|
+
matches "dog"
|
29
|
+
|
30
|
+
subcommand "fetch" do
|
31
|
+
matches "fetch"
|
32
|
+
action { "*runs and fetches*" }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
18
36
|
task "say hi" do |t|
|
19
37
|
t.every "1m"
|
20
38
|
t.action { "hello!" }
|
@@ -27,7 +45,7 @@ CONFIG
|
|
27
45
|
describe "#parse" do
|
28
46
|
it "parses a string into an array of commands" do
|
29
47
|
config = Dog::Configure.parse config_string
|
30
|
-
command = config.
|
48
|
+
command = config.get_command("greet")
|
31
49
|
|
32
50
|
command.respond_to("hi").must_equal "hello!"
|
33
51
|
command.respond_to("hello").must_equal "hello!"
|
@@ -35,14 +53,22 @@ CONFIG
|
|
35
53
|
end
|
36
54
|
|
37
55
|
it "parses subcommands" do
|
38
|
-
config = Dog::Configure.parse
|
39
|
-
command = config.
|
56
|
+
config = Dog::Configure.parse(config_string)
|
57
|
+
command = config.get_command("greet")
|
40
58
|
|
41
59
|
command.respond_to("hi yo").must_equal "yo yo yo, hello!"
|
42
60
|
end
|
43
61
|
|
62
|
+
it "parses subcommands into one top level command from many config entries" do
|
63
|
+
config = Dog::Configure.parse(config_string)
|
64
|
+
command = config.get_command("dog")
|
65
|
+
|
66
|
+
command.respond_to("dog pet").must_equal "*wags tail*"
|
67
|
+
command.respond_to("dog fetch").must_equal "*runs and fetches*"
|
68
|
+
end
|
69
|
+
|
44
70
|
it "parses a string into an array of scheduled tasks" do
|
45
|
-
config = Dog::Configure.parse
|
71
|
+
config = Dog::Configure.parse(config_string)
|
46
72
|
task = config.scheduled_tasks.first
|
47
73
|
|
48
74
|
task.run({}).must_equal "hello!"
|
@@ -50,13 +76,13 @@ CONFIG
|
|
50
76
|
end
|
51
77
|
|
52
78
|
it "parses default chat rooms from a config string" do
|
53
|
-
config = Dog::Configure.parse
|
79
|
+
config = Dog::Configure.parse(config_string)
|
54
80
|
|
55
81
|
config.chat_rooms.first.must_equal "test_room"
|
56
82
|
end
|
57
83
|
|
58
84
|
it "parses multiple chat rooms from a config string" do
|
59
|
-
config = Dog::Configure.parse
|
85
|
+
config = Dog::Configure.parse(config_string)
|
60
86
|
|
61
87
|
config.chat_rooms.must_equal ["test_room", "test_room2"]
|
62
88
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dog-bot
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-11-
|
12
|
+
date: 2012-11-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: blather
|
16
|
-
requirement: &
|
16
|
+
requirement: &21646340 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 0.8.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *21646340
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: google_image_api
|
27
|
-
requirement: &
|
27
|
+
requirement: &21645860 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: 0.0.1
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *21645860
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rufus-scheduler
|
38
|
-
requirement: &
|
38
|
+
requirement: &21645400 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: 2.0.17
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *21645400
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rake
|
49
|
-
requirement: &
|
49
|
+
requirement: &21644940 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
@@ -54,7 +54,7 @@ dependencies:
|
|
54
54
|
version: 0.9.2.2
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *21644940
|
58
58
|
description: Chatbot
|
59
59
|
email:
|
60
60
|
- ben@bmdev.org
|
@@ -70,17 +70,23 @@ files:
|
|
70
70
|
- README.md
|
71
71
|
- Rakefile
|
72
72
|
- bin/dog
|
73
|
+
- config_examples/default_rooms.rb
|
74
|
+
- config_examples/dog.rb
|
75
|
+
- config_examples/google_image.rb
|
76
|
+
- config_examples/jenkins.rb
|
77
|
+
- config_examples/ruby_gems.rb
|
78
|
+
- config_examples/tasks.rb
|
79
|
+
- config_examples/twitter.rb
|
80
|
+
- config_examples/xkcd.rb
|
73
81
|
- dog.gemspec
|
74
|
-
- dog_config_example.rb
|
75
82
|
- lib/dog.rb
|
76
83
|
- lib/dog/bot.rb
|
77
|
-
- lib/dog/brain.rb
|
78
84
|
- lib/dog/command.rb
|
79
85
|
- lib/dog/configure.rb
|
80
86
|
- lib/dog/connection.rb
|
81
87
|
- lib/dog/scheduled_task.rb
|
88
|
+
- lib/dog/scheduler.rb
|
82
89
|
- spec/dog/bot_spec.rb
|
83
|
-
- spec/dog/brain_spec.rb
|
84
90
|
- spec/dog/command_spec.rb
|
85
91
|
- spec/dog/configure_spec.rb
|
86
92
|
- spec/dog/scheduled_task_spec.rb
|
@@ -110,7 +116,6 @@ specification_version: 3
|
|
110
116
|
summary: Extensible XMPP chatbot
|
111
117
|
test_files:
|
112
118
|
- spec/dog/bot_spec.rb
|
113
|
-
- spec/dog/brain_spec.rb
|
114
119
|
- spec/dog/command_spec.rb
|
115
120
|
- spec/dog/configure_spec.rb
|
116
121
|
- spec/dog/scheduled_task_spec.rb
|
data/dog_config_example.rb
DELETED
@@ -1,59 +0,0 @@
|
|
1
|
-
chat_rooms "dog_test", "dog_test2"
|
2
|
-
|
3
|
-
command "get body of tweet" do
|
4
|
-
matches /twitter\.com/
|
5
|
-
action do |message|
|
6
|
-
id = message.split("/").last
|
7
|
-
uri = URI.parse "https://api.twitter.com/1/statuses/show.json?id=#{id}"
|
8
|
-
tweet = JSON.parse uri.open.read
|
9
|
-
|
10
|
-
"#{tweet["text"]} - @#{tweet["user"]["screen_name"]}"
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
command "dog" do
|
15
|
-
matches "dog"
|
16
|
-
action { "bark!" }
|
17
|
-
|
18
|
-
subcommand "xkcd" do
|
19
|
-
matches "xkcd"
|
20
|
-
action do
|
21
|
-
uri = URI.parse "http://xkcd.com/info.0.json"
|
22
|
-
comic = JSON.parse uri.open.read
|
23
|
-
"#{comic["img"]}\n#{comic["alt"]}"
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
subcommand "fetch image" do
|
28
|
-
matches "fetch", "image"
|
29
|
-
action do |message|
|
30
|
-
query = message.split(" ")[2..-1].join(" ")
|
31
|
-
GoogleImageApi.find(query).images.first["url"]
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
subcommand "ruby gems" do
|
36
|
-
matches "gem"
|
37
|
-
action do |message|
|
38
|
-
begin
|
39
|
-
gem_name = message.split(" ").last
|
40
|
-
uri = URI.parse "http://rubygems.org/api/v1/gems/#{gem_name}.json"
|
41
|
-
gem = JSON.parse uri.open.read
|
42
|
-
|
43
|
-
"'#{gem["name"]}' version: #{gem["version"]} downloads: #{gem["downloads"]}"
|
44
|
-
rescue
|
45
|
-
"gem not found"
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
subcommand "join channel" do
|
51
|
-
matches "join"
|
52
|
-
action { :join }
|
53
|
-
end
|
54
|
-
|
55
|
-
subcommand "reload config" do
|
56
|
-
matches "reload"
|
57
|
-
action { :reload }
|
58
|
-
end
|
59
|
-
end
|
data/lib/dog/brain.rb
DELETED
data/spec/dog/brain_spec.rb
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
require "minitest/spec"
|
2
|
-
require "minitest/autorun"
|
3
|
-
|
4
|
-
require_relative "../../lib/dog/brain"
|
5
|
-
|
6
|
-
describe Dog::Brain do
|
7
|
-
subject { Dog::Brain.new :foo => :bar }
|
8
|
-
|
9
|
-
it "can be created without inital data" do
|
10
|
-
brain = Dog::Brain.new
|
11
|
-
brain.get(:foo).must_be_nil
|
12
|
-
end
|
13
|
-
|
14
|
-
describe "get" do
|
15
|
-
it "gets a value for a key" do
|
16
|
-
subject.get(:foo).must_equal :bar
|
17
|
-
end
|
18
|
-
|
19
|
-
it "gets nil for an unknown key" do
|
20
|
-
subject.get(:bad_key).must_be_nil
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
describe "set" do
|
25
|
-
it "sets a key to a value" do
|
26
|
-
subject.set(:baz, :foz)
|
27
|
-
subject.get(:baz).must_equal :foz
|
28
|
-
end
|
29
|
-
|
30
|
-
it "can overwrite existing values" do
|
31
|
-
subject.set(:foo, :baz)
|
32
|
-
subject.get(:foo).must_equal :baz
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|