botfly 0.2.1 → 0.3.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/VERSION +1 -1
- data/botfly.gemspec +3 -2
- data/lib/botfly.rb +5 -3
- data/lib/botfly/bot.rb +21 -14
- data/lib/botfly/common_block_acceptor.rb +1 -1
- data/lib/botfly/matcher/matcher.rb +1 -0
- data/lib/botfly/muc_client.rb +5 -5
- data/lib/botfly/responder/muc_responder.rb +5 -1
- data/lib/botfly/responder/subscription_request_responder.rb +17 -0
- data/retrobot.rb +33 -22
- metadata +5 -4
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.3.0
|
data/botfly.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{botfly}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.3.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Ryan Neufeld"]
|
12
|
-
s.date = %q{2010-03-
|
12
|
+
s.date = %q{2010-03-28}
|
13
13
|
s.description = %q{Botfly is a Jabber Bot DSL that lets you write bots with ease. Enjoy, while it's still fresh and VERY ALPHA.}
|
14
14
|
s.email = %q{ryan@ryanneufeld.ca}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -43,6 +43,7 @@ Gem::Specification.new do |s|
|
|
43
43
|
"lib/botfly/responder/muc_responder.rb",
|
44
44
|
"lib/botfly/responder/presence_responder.rb",
|
45
45
|
"lib/botfly/responder/responder.rb",
|
46
|
+
"lib/botfly/responder/subscription_request_responder.rb",
|
46
47
|
"retrobot.rb",
|
47
48
|
"spec/botfly_spec.rb",
|
48
49
|
"spec/spec.opts",
|
data/lib/botfly.rb
CHANGED
@@ -2,8 +2,7 @@ require 'rubygems'
|
|
2
2
|
|
3
3
|
require 'xmpp4r'
|
4
4
|
require 'xmpp4r/muc'
|
5
|
-
require '
|
6
|
-
require 'logger'
|
5
|
+
require 'xmpp4r/roster'
|
7
6
|
|
8
7
|
require 'botfly/common_block_acceptor'
|
9
8
|
require 'botfly/responder'
|
@@ -11,6 +10,9 @@ require 'botfly/bot'
|
|
11
10
|
require 'botfly/matcher'
|
12
11
|
require 'botfly/muc_client'
|
13
12
|
|
13
|
+
require 'logger'
|
14
|
+
require 'forwardable'
|
15
|
+
|
14
16
|
Thread.abort_on_exception = true
|
15
17
|
|
16
18
|
module Botfly
|
@@ -22,7 +24,7 @@ module Botfly
|
|
22
24
|
@logfile = logfile
|
23
25
|
Botfly.logger.info("BOTFLY: #login")
|
24
26
|
bot = Botfly::Bot.new(jid,pass)
|
25
|
-
bot.connect
|
27
|
+
bot.connect # Must connect first, since MUC requires an active connection to initiate
|
26
28
|
bot.instance_exec(&block)
|
27
29
|
return bot # At this point doesn't get returned, as the thread is stopped
|
28
30
|
end
|
data/lib/botfly/bot.rb
CHANGED
@@ -2,51 +2,58 @@ require 'rubygems'
|
|
2
2
|
|
3
3
|
module Botfly
|
4
4
|
class Bot < CommonBlockAcceptor
|
5
|
-
|
5
|
+
attr_accessor :responders, :client, :roster, :jid
|
6
6
|
|
7
|
-
def initialize(jid,pass)
|
7
|
+
def initialize(jid,pass, opts = {})
|
8
8
|
super
|
9
9
|
Botfly.logger.info(" BOT: Bot#new")
|
10
10
|
@password = pass
|
11
11
|
@jid = Jabber::JID.new(jid)
|
12
12
|
@client = Jabber::Client.new(@jid)
|
13
13
|
@main_thread = Thread.current
|
14
|
+
if opts[:gtalk]
|
15
|
+
@host = "talk.google.com"
|
16
|
+
end
|
14
17
|
end
|
15
18
|
|
16
19
|
def connect
|
17
|
-
Botfly.logger.info(" BOT: Connecting to #{@jid}...")
|
18
|
-
@client.connect
|
20
|
+
Botfly.logger.info(" BOT: Connecting to #{@host || @jid}...")
|
21
|
+
@client.connect(@host)
|
19
22
|
@client.auth(@password)
|
20
23
|
Botfly.logger.info(" BOT: Connected")
|
21
24
|
register_for_callbacks
|
22
25
|
@client.send(Jabber::Presence.new.set_status("Carrier has arrived"))
|
26
|
+
@roster = Jabber::Roster::Helper.new(@client)
|
23
27
|
#Thread.stop
|
24
28
|
end
|
25
|
-
|
29
|
+
|
26
30
|
def join(room_name,&block)
|
27
31
|
return Botfly::MUCClient.new(room_name,self,&block)
|
28
32
|
end
|
29
|
-
|
33
|
+
|
30
34
|
def quit
|
31
35
|
@client.close
|
32
36
|
@main_thread.continue
|
33
37
|
end
|
34
|
-
|
35
|
-
def to_debug_s
|
36
|
-
|
37
|
-
end
|
38
|
-
|
38
|
+
|
39
|
+
def to_debug_s; "BOT"; end
|
40
|
+
|
39
41
|
private
|
40
42
|
|
41
43
|
def register_for_callbacks
|
42
44
|
Botfly.logger.info(" BOT: Registering for callbacks with client")
|
43
45
|
# @client.add_update_callback {|presence| respond_to(:update, :presence => presence) }
|
44
|
-
|
45
|
-
|
46
|
+
@client.add_subscription_request_callback do |item, pres| # requires Roster helper
|
47
|
+
Botfly.logger.debug(" CB: Got Message")
|
48
|
+
respond_to(:subscription_request, :roster_item => item, :presence => pres)
|
49
|
+
end
|
50
|
+
|
51
|
+
@client.add_message_callback do |message|
|
46
52
|
Botfly.logger.debug(" CB: Got Message")
|
47
53
|
respond_to(:message, :message => message)
|
48
54
|
end
|
49
|
-
|
55
|
+
|
56
|
+
@client.add_presence_callback do |new_presence,old_presence|
|
50
57
|
Botfly.logger.debug(" CB: Got Presence")
|
51
58
|
respond_to(:presence, :old => old_presence, :new => new_presence)
|
52
59
|
end
|
@@ -24,7 +24,7 @@ module Botfly
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def remove_responder(id_to_remove)
|
27
|
-
Botfly.logger.info("
|
27
|
+
Botfly.logger.info("#{self.to_debug_s}: Removing responder #{id_to_remove}")
|
28
28
|
@responders.each { |pair| key,chain = pair; chain.reject! {|r| r.id == id_to_remove } }
|
29
29
|
end
|
30
30
|
|
data/lib/botfly/muc_client.rb
CHANGED
@@ -4,7 +4,7 @@ module Botfly
|
|
4
4
|
class MUCClient < CommonBlockAcceptor
|
5
5
|
attr_reader :bot, :muc
|
6
6
|
|
7
|
-
def room;
|
7
|
+
def room; @block_state; end
|
8
8
|
|
9
9
|
def initialize(room, bot, &block)
|
10
10
|
super
|
@@ -13,7 +13,7 @@ module Botfly
|
|
13
13
|
@client = @bot.client
|
14
14
|
@room = room
|
15
15
|
@domain = "conference.#{@bot.jid.domain}" # A sensible default for now
|
16
|
-
@resource = @bot.jid.
|
16
|
+
@resource = @bot.jid.node
|
17
17
|
|
18
18
|
execute(&block) if block_given? # i.e. join(room) do ... end
|
19
19
|
return self
|
@@ -30,8 +30,7 @@ module Botfly
|
|
30
30
|
|
31
31
|
|
32
32
|
def respond_to(callback_type, params)
|
33
|
-
|
34
|
-
if !params[:time].nil? # Only respond to messages from the server, if time is nil server didn't send
|
33
|
+
if (params[:nick] != @resource && Time.now > @connected_at_time + 3)#seconds # Don't run callbacks on the slew of launch messages (at least until I figure out a better way to differentiate them)
|
35
34
|
Botfly.logger.info("MUC: Responding to callback of type: #{callback_type} with time of #{params[:time]}")
|
36
35
|
@responders[callback_type].each {|r| r.callback_with params} if @responders[callback_type]
|
37
36
|
end
|
@@ -46,6 +45,7 @@ module Botfly
|
|
46
45
|
@muc = Jabber::MUC::SimpleMUCClient.new(@bot.client)
|
47
46
|
register_for_callbacks
|
48
47
|
@jid = Jabber::JID.new("#{@room}@#{@domain}/#{@resource}")
|
48
|
+
@connected_at_time = Time.now
|
49
49
|
@muc.join(@jid)
|
50
50
|
Botfly.logger.info("MUC: Done connecting")
|
51
51
|
end
|
@@ -64,7 +64,7 @@ module Botfly
|
|
64
64
|
#@muc.on_private_message {|time,nick,text| respond_to(:private_message, :time=>time,:nick=>nick,:text=>text)} # Low on the priority to impl. list
|
65
65
|
@muc.on_room_message {|time,text| respond_to(:room_message, :time => time, :text => text)}
|
66
66
|
@muc.on_self_leave {|time| respond_to(:self_leave, :time => time) }
|
67
|
-
@muc.on_subject {|time,nick,subject| respond_to(:subject, :time => time, :nick =>
|
67
|
+
@muc.on_subject {|time,nick,subject| respond_to(:subject, :time => time, :nick => nick, :subject => subject)}
|
68
68
|
end
|
69
69
|
end
|
70
70
|
end
|
@@ -18,7 +18,8 @@ module Botfly
|
|
18
18
|
@id = @@id += 1
|
19
19
|
end
|
20
20
|
|
21
|
-
def method_missing(method
|
21
|
+
def method_missing(method,*args,&block)
|
22
|
+
condition = args.first
|
22
23
|
Botfly.logger.info("RSP: Responder##{method}(#{condition.inspect})")
|
23
24
|
|
24
25
|
add_matcher(method,condition)
|
@@ -51,6 +52,9 @@ module Botfly
|
|
51
52
|
@muc.muc.say(msg)
|
52
53
|
end
|
53
54
|
|
55
|
+
def remove(responder_id)
|
56
|
+
@muc.remove_responder(responder_id)
|
57
|
+
end
|
54
58
|
private
|
55
59
|
def add_matcher(method, condition)
|
56
60
|
klass = Botfly.const_get("MUC" + method.to_s.capitalize + "Matcher")
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Botfly
|
2
|
+
class SubscriptionRequestResponder < Responder
|
3
|
+
extend Forwardable
|
4
|
+
def setup_instance_variables(params)
|
5
|
+
Botfly.logger.debug(" RSP: SubscriptionRequestResponder setting up instance variables")
|
6
|
+
@roster_item = params[:roster_item]
|
7
|
+
@presence = params[:presence]
|
8
|
+
@from = @presence.from
|
9
|
+
end
|
10
|
+
|
11
|
+
def accept
|
12
|
+
@bot.roster.accept_subscription(@from)
|
13
|
+
end
|
14
|
+
def decline
|
15
|
+
@bot.roster.decline_subscription(@from)
|
16
|
+
end
|
17
|
+
end
|
data/retrobot.rb
CHANGED
@@ -4,40 +4,51 @@ require 'fileutils'
|
|
4
4
|
require 'yaml'
|
5
5
|
|
6
6
|
config = YAML::load(ARGF.read) if ARGF
|
7
|
-
|
7
|
+
#Jabber::debug = true
|
8
8
|
bot = Botfly.login(config["jid"],config["pass"]) do
|
9
9
|
join('lazer').as('retro-bot') do
|
10
|
-
on.message.from(/^rkneufeld/).body(
|
11
|
-
say "All votes are now being tallied. You have three votes, use them wisely"
|
12
|
-
say
|
13
|
-
|
10
|
+
on.message.from(/^rkneufeld/).body(/^@retro start voting/) do
|
11
|
+
say "All votes are now being tallied. You have three votes, use them wisely."
|
12
|
+
say "================="
|
13
|
+
|
14
|
+
room[:votes] = {}
|
14
15
|
room[:votes_responder] = on.message.body(/(\d+)+/) do
|
15
|
-
@body.scan(/(\d+)+/).map
|
16
|
+
@body.scan(/(\d+)+/).map do |m|
|
17
|
+
room[:votes][@from] ||= []
|
18
|
+
room[:votes][@from] << m.first.to_i
|
19
|
+
end
|
16
20
|
end
|
17
21
|
end
|
18
|
-
on.message.from(/^rkneufeld/).body(
|
19
|
-
say
|
20
|
-
say "Allright, voting is finished"
|
22
|
+
on.message.from(/^rkneufeld/).body(/^@retro stop voting/) do
|
23
|
+
say "================="
|
24
|
+
say "Allright, voting is finished. Here are the results:"
|
25
|
+
|
26
|
+
puts "Raw data: #{room[:votes].inspect}"
|
21
27
|
remove room[:votes_responder]
|
28
|
+
room[:votes] = room[:votes].map{ |pair| pair[1].first(3) }.flatten
|
22
29
|
sorted = room[:votes].inject({}) do |h,n|
|
23
30
|
h[n] ||= 0
|
24
31
|
h[n] += 1
|
25
32
|
h
|
26
33
|
end.sort {|a,b| b[-1] <=> a[-1] }
|
27
|
-
|
28
|
-
|
29
|
-
on.message.from(/^rkneufeld/).body(/^rb tally$/) do
|
30
|
-
room[:tally_responders] = []
|
31
|
-
room[:plus] = {}; room[:minus] = {}; room[:delta] = {}
|
32
|
-
room[:tally_responders] << on.message.body(/^+(.*)/) { room[:plus][from] ||= []; room[:plus][from] << match }
|
33
|
-
room[:tally_responders] << on.message.body(/^∂(.*)/) { room[:delta][from] ||= []; room[:delta][from] << match }
|
34
|
-
room[:tally_responders] << on.message.body(/^-(.*)/) { room[:minus][from] ||= []; room[:minus][from] << match }
|
35
|
-
end
|
36
|
-
on.message.from(/^rkneufeld/).body(/^rb stop tally/) do
|
37
|
-
# remove responders
|
38
|
-
# tally messages
|
39
|
-
# stored to room[:voted]
|
34
|
+
|
35
|
+
sorted.each {|pair| say "#{pair[0]} => #{pair[-1]}"}#)}" : #{room[:voted][pair[0]].person} - #{room[:voted][pair[0]].name}" }
|
40
36
|
end
|
37
|
+
# on.message.from(/^rkneufeld/).body(/^rb tally$/) do
|
38
|
+
# say "Tally HO! Please start your message with +, -, or ∂ (that's option-d) to have it tallied up"
|
39
|
+
# say "================="
|
40
|
+
# room[:tally_responders] = []; room[:tally] = {}
|
41
|
+
# room[:plus] = {}; room[:minus] = {}; room[:delta] = {}
|
42
|
+
#
|
43
|
+
# room[:tally_responders] << on.message.body(/^\+(.*)/) { room[:tally][@from] ||= []; room[:tally][@from] << @body }
|
44
|
+
# room[:tally_responders] << on.message.body(/^d (.*)/) { room[:tally][@from] ||= []; room[:tally][@from] << @body }
|
45
|
+
# room[:tally_responders] << on.message.body(/^-(.*)/) { room[:tally][@from] ||= []; room[:tally][@from] << @body }
|
46
|
+
# end
|
47
|
+
# on.message.from(/^rkneufeld/).body(/^rb stop tally/) do
|
48
|
+
# room[:tally_responders].each { |id| remove id }
|
49
|
+
# room[:tally]
|
50
|
+
# # stored to room[:voted]
|
51
|
+
# end
|
41
52
|
end
|
42
53
|
end
|
43
54
|
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 0.
|
7
|
+
- 3
|
8
|
+
- 0
|
9
|
+
version: 0.3.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Ryan Neufeld
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-03-
|
17
|
+
date: 2010-03-28 00:00:00 -06:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -80,6 +80,7 @@ files:
|
|
80
80
|
- lib/botfly/responder/muc_responder.rb
|
81
81
|
- lib/botfly/responder/presence_responder.rb
|
82
82
|
- lib/botfly/responder/responder.rb
|
83
|
+
- lib/botfly/responder/subscription_request_responder.rb
|
83
84
|
- retrobot.rb
|
84
85
|
- spec/botfly_spec.rb
|
85
86
|
- spec/spec.opts
|