botfly 0.1.1 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,9 +1,19 @@
1
- = botfly
1
+ = Botfly
2
2
 
3
- Description goes here.
3
+ Botfly is a Jabber Bot DSL that makes writing bots a joy.
4
+
5
+ == Installation
6
+
7
+ gem install botfly
8
+
9
+ Go nuts!
10
+
11
+ == Usage
12
+
13
+ Coming soon, for now take a look at `example.rb`
4
14
 
5
15
  == Note on Patches/Pull Requests
6
-
16
+
7
17
  * Fork the project.
8
18
  * Make your feature addition or bug fix.
9
19
  * Add tests for it. This is important so I don't break it in a
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.1
1
+ 0.2.1
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{botfly}
8
- s.version = "0.1.1"
8
+ s.version = "0.2.1"
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-13}
12
+ s.date = %q{2010-03-17}
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 = [
@@ -17,8 +17,7 @@ Gem::Specification.new do |s|
17
17
  "README.rdoc"
18
18
  ]
19
19
  s.files = [
20
- ".document",
21
- ".gitignore",
20
+ ".gitignore",
22
21
  "LICENSE",
23
22
  "README.rdoc",
24
23
  "Rakefile",
@@ -27,15 +26,24 @@ Gem::Specification.new do |s|
27
26
  "example.rb",
28
27
  "lib/botfly.rb",
29
28
  "lib/botfly/bot.rb",
29
+ "lib/botfly/common_block_acceptor.rb",
30
30
  "lib/botfly/matcher.rb",
31
31
  "lib/botfly/matcher/body_matcher.rb",
32
32
  "lib/botfly/matcher/matcher.rb",
33
+ "lib/botfly/matcher/muc_nick_matcher.rb",
34
+ "lib/botfly/matcher/muc_text_matcher.rb",
35
+ "lib/botfly/matcher/muc_time_matcher.rb",
33
36
  "lib/botfly/matcher/nick_matcher.rb",
34
37
  "lib/botfly/matcher/subject_matcher.rb",
38
+ "lib/botfly/muc_client.rb",
35
39
  "lib/botfly/responder.rb",
40
+ "lib/botfly/responder/common_responder_methods.rb",
36
41
  "lib/botfly/responder/message_responder.rb",
42
+ "lib/botfly/responder/muc_message_responder.rb",
43
+ "lib/botfly/responder/muc_responder.rb",
37
44
  "lib/botfly/responder/presence_responder.rb",
38
45
  "lib/botfly/responder/responder.rb",
46
+ "retrobot.rb",
39
47
  "spec/botfly_spec.rb",
40
48
  "spec/spec.opts",
41
49
  "spec/spec_helper.rb"
data/example.rb CHANGED
@@ -1,24 +1,39 @@
1
1
  require 'rubygems'
2
2
  require 'botfly'
3
-
3
+ require 'fileutils'
4
4
  require 'yaml'
5
5
 
6
6
  config = YAML::load(ARGF.read) if ARGF
7
- puts config.inspect
8
-
9
- Jabber::debug = false
10
7
 
11
8
  bot = Botfly.login(config["jid"],config["pass"]) do
12
- on(:message).body(/^exit$/) { reply "Goodbye!"; quit }
13
- on(:message).nick(/rkneufeld/) do
14
- Botfly.logger.info("Callback called")
15
- @count ||= 0
16
- @count += 1
17
- reply("That's the #{@count}th message I've received.")
18
- end
9
+ blame_responder = on.message.body(/^blame/) do |a|
10
+ match = @body.match(/^blame (.*):(.*)$/)
11
+ file = match[1]
12
+ line = match[2].to_i
13
+
14
+ project = "/Users/burke/src/jsgithistory"
15
+
16
+ result=nil
17
+ FileUtils.cd(project) do
18
+ result = `git blame -p -L#{line},#{line} #{file}`
19
+ end
19
20
 
20
- on(:presence) { puts self }
21
- connect
21
+ author = result.scan(/author (.*)\n/).first
22
+ time = Time.at(result.scan(/author-time (.*)\n/).first.to_i)
23
+ commit = result.lines.first.split(' ').first.strip
24
+
25
+ reply "#{author}, #{time}, #{commit}"
26
+ end
27
+ join('bots') do
28
+ on.message do
29
+ reply "Hi"
30
+ end
31
+ end
32
+ on.message.from(/^rkneufeld/).body(/^kb$/) do
33
+ reply "Sure thing! You ARE the boss!"
34
+ remove blame_responder
35
+ reply "There, all done"
36
+ end
22
37
  end
23
- Thread.stop
24
- loop{}
38
+
39
+ Thread.stop;loop
@@ -2,12 +2,16 @@ require 'rubygems'
2
2
 
3
3
  require 'xmpp4r'
4
4
  require 'xmpp4r/muc'
5
+ require 'forwardable'
6
+ require 'logger'
5
7
 
8
+ require 'botfly/common_block_acceptor'
6
9
  require 'botfly/responder'
7
10
  require 'botfly/bot'
8
11
  require 'botfly/matcher'
12
+ require 'botfly/muc_client'
9
13
 
10
- require 'logger'
14
+ Thread.abort_on_exception = true
11
15
 
12
16
  module Botfly
13
17
  def Botfly.logger
@@ -18,7 +22,8 @@ module Botfly
18
22
  @logfile = logfile
19
23
  Botfly.logger.info("BOTFLY: #login")
20
24
  bot = Botfly::Bot.new(jid,pass)
21
- bot.instance_eval(&block)
25
+ bot.connect
26
+ bot.instance_exec(&block)
22
27
  return bot # At this point doesn't get returned, as the thread is stopped
23
28
  end
24
- end
29
+ end
@@ -1,14 +1,15 @@
1
1
  require 'rubygems'
2
2
 
3
3
  module Botfly
4
- class Bot
5
- attr_reader :responders, :client
4
+ class Bot < CommonBlockAcceptor
5
+ attr_reader :jid
6
+
6
7
  def initialize(jid,pass)
8
+ super
7
9
  Botfly.logger.info(" BOT: Bot#new")
8
10
  @password = pass
9
11
  @jid = Jabber::JID.new(jid)
10
12
  @client = Jabber::Client.new(@jid)
11
- @responders = {}
12
13
  @main_thread = Thread.current
13
14
  end
14
15
 
@@ -17,27 +18,27 @@ module Botfly
17
18
  @client.connect
18
19
  @client.auth(@password)
19
20
  Botfly.logger.info(" BOT: Connected")
20
- register_for_xmpp_callbacks
21
+ register_for_callbacks
21
22
  @client.send(Jabber::Presence.new.set_status("Carrier has arrived"))
22
23
  #Thread.stop
23
24
  end
24
25
 
25
- def on(type, &block)
26
- Botfly.logger.info(" BOT: Bot#on")
27
- klass = Botfly.const_get(type.to_s.capitalize + "Responder")
28
- (@responders[type] ||= []) << responder = klass.new(@client, self, &block)
29
- Botfly.logger.info(" BOT: #{type.to_s.capitalize}Responder added to responder chain")
30
- return responder
26
+ def join(room_name,&block)
27
+ return Botfly::MUCClient.new(room_name,self,&block)
31
28
  end
32
29
 
33
30
  def quit
34
31
  @client.close
35
32
  @main_thread.continue
36
33
  end
37
-
34
+
35
+ def to_debug_s
36
+ "BOT"
37
+ end
38
+
38
39
  private
39
40
 
40
- def register_for_xmpp_callbacks
41
+ def register_for_callbacks
41
42
  Botfly.logger.info(" BOT: Registering for callbacks with client")
42
43
  # @client.add_update_callback {|presence| respond_to(:update, :presence => presence) }
43
44
  # @client.add_subscription_request_callback {|item, pres| } # requires Roster helper
@@ -45,7 +46,7 @@ module Botfly
45
46
  Botfly.logger.debug(" CB: Got Message")
46
47
  respond_to(:message, :message => message)
47
48
  end
48
- @client.add_presence_callback do |old_presence,new_presence|
49
+ @client.add_presence_callback do |new_presence,old_presence|
49
50
  Botfly.logger.debug(" CB: Got Presence")
50
51
  respond_to(:presence, :old => old_presence, :new => new_presence)
51
52
  end
@@ -54,20 +55,7 @@ module Botfly
54
55
 
55
56
  def respond_to(callback_type, params)
56
57
  Botfly.logger.info(" BOT: Responding to callback of type: #{callback_type}")
57
- responders = params[:muc] ? @muc_responders[params[:muc]] : @responders
58
- responders[callback_type].each {|r| r.callback_with params} if responders[callback_type]
58
+ @responders[callback_type].each {|r| r.callback_with params} if @responders[callback_type]
59
59
  end
60
-
61
- # def register_for_muc_callbacks(client)
62
- # params = {:muc => client}
63
- ## client.on_join {|time,nick| respond_to(:join, params.merge!(:time=>time,:nick=>nick))}
64
- # client.on_leave {|time,nick| respond_to(:leave, params.merge!(:time=>time,:nick=>nick))}
65
- # client.on_message {|time,nick,text| respond_to(:message, params.merge!(:time=>time,:nick=>nick,:text=>text))}
66
- # client.on_private_message {|time,nick,text| respond_to(:private_message, params.merge!(:time=>time,:nick=>nick,:text=>text))}
67
- # client.on_room_message {|time,text| respond_to(:room_message, params.merge!(:time => time, :text => text))}
68
- # client.on_self_leave {|time| respond_to(:self_leave, params.merge!(:time => time)) }
69
- # client.on_subject {|time,nick,subject| respond_to(:subject, params.merge!(:time => time, :nick => nickname, :subject => subject))}
70
- # end
71
-
72
60
  end
73
- end
61
+ end
@@ -0,0 +1,51 @@
1
+ module Botfly
2
+ class CommonBlockAcceptor
3
+ extend Forwardable
4
+
5
+ attr_accessor :responders
6
+ attr_reader :client
7
+
8
+ def initialize(ignored,ignore)
9
+ @block_state = {}
10
+ @responders = {}
11
+ end
12
+
13
+ ABSTRACT_RAISE_ERROR = "AbstractMethodError: Implement in subclass"
14
+ def to_debug_s; raise ABSTRACT_RAISE_ERROR; end
15
+ def respond_to(type,params); raise ABSTRACT_RAISE_ERROR; end
16
+ def on; raise ABSTRACT_RAISE_ERROR; end
17
+
18
+ def [](key)
19
+ @block_state[key]
20
+ end
21
+
22
+ def []=(key, set_to)
23
+ @block_state[key] = set_to
24
+ end
25
+
26
+ def remove_responder(id_to_remove)
27
+ Botfly.logger.info("BOT: Removing responder #{id_to_remove}")
28
+ @responders.each { |pair| key,chain = pair; chain.reject! {|r| r.id == id_to_remove } }
29
+ end
30
+
31
+ def on
32
+ return OnRecognizer.new(self)
33
+ end
34
+
35
+ class OnRecognizer
36
+ def initialize(obj); @obj = obj; end
37
+
38
+ def method_missing(type,&block)
39
+ Botfly.logger.info("#{@obj.to_debug_s}: Bot#on")
40
+ klass = Botfly.const_get(@obj.class_prefix + type.to_s.capitalize + "Responder")
41
+ (@obj.responders[type] ||= []) << responder = klass.new(@obj, &block)
42
+ Botfly.logger.info("#{@obj.to_debug_s}: #{@obj.class_prefix}#{type.to_s.capitalize}Responder added to responder chain")
43
+ return responder
44
+ end
45
+ end
46
+
47
+ def class_prefix
48
+ ''
49
+ end
50
+ end
51
+ end
@@ -2,4 +2,8 @@ require 'botfly/matcher/matcher'
2
2
  # TODO: Scope the matchers by responder
3
3
  require 'botfly/matcher/nick_matcher'
4
4
  require 'botfly/matcher/body_matcher'
5
- require 'botfly/matcher/subject_matcher'
5
+ require 'botfly/matcher/subject_matcher'
6
+
7
+ require 'botfly/matcher/muc_nick_matcher'
8
+ require 'botfly/matcher/muc_text_matcher'
9
+ require 'botfly/matcher/muc_time_matcher'
@@ -5,8 +5,8 @@ module Botfly
5
5
  class BodyMatcher < Matcher
6
6
  def match(params)
7
7
  msg = params[:message]
8
- Botfly.logger.debug " MCH: Matching #{@condition.inspect} against #{msg.body.inspect}"
9
- Botfly.logger.debug " RESULT: #{(msg.body =~ @condition).inspect}"
8
+ Botfly.logger.debug "MCH: Matching #{@condition.inspect} against #{msg.body.inspect}"
9
+ Botfly.logger.debug "RESULT: #{(msg.body =~ @condition).inspect}"
10
10
  return msg.body =~ @condition
11
11
  end
12
12
  end
@@ -1,7 +1,7 @@
1
1
  module Botfly
2
2
  class Matcher
3
3
  def initialize(condition)
4
- Botfly.logger.info(" MCH: Creating Matcher")
4
+ Botfly.logger.info("MCH: Creating Matcher")
5
5
  @condition = condition
6
6
  end
7
7
  def match(params)
@@ -0,0 +1,13 @@
1
+ require 'botfly/matcher'
2
+
3
+ module Botfly
4
+ class MUCNickMatcher < Matcher
5
+ def match(params)
6
+ nick = params[:nick]
7
+ Botfly.logger.debug "MCH: Matching #{@condition.inspect} against #{nick}"
8
+ Botfly.logger.debug "RESULT: #{(nick =~ @condition).inspect}"
9
+ return nick =~ @condition
10
+ end
11
+ end
12
+ MUCFromMatcher = MUCNickMatcher
13
+ end
@@ -0,0 +1,13 @@
1
+ require 'botfly/matcher'
2
+
3
+ module Botfly
4
+ class MUCTextMatcher < Matcher
5
+ def match(params)
6
+ text = params[:text]
7
+ Botfly.logger.debug "MCH: Matching #{@condition.inspect} against #{text}"
8
+ Botfly.logger.debug "RESULT: #{(text =~ @condition).inspect}"
9
+ return text =~ @condition
10
+ end
11
+ end
12
+ MUCBodyMatcher = MUCTextMatcher
13
+ end
@@ -0,0 +1,14 @@
1
+ require 'botfly/matcher'
2
+
3
+ # FIXME: Make time matching much more robust
4
+ module Botfly
5
+ class MUCTimeMatcher < Matcher
6
+ def match(params)
7
+ time = params[:time]
8
+ Botfly.logger.debug "MCH: Matching #{@condition.inspect} against #{time}"
9
+ Botfly.logger.debug "RESULT: #{(time =~ @condition).inspect}"
10
+ return time =~ @condition
11
+ end
12
+ end
13
+
14
+ end
@@ -5,9 +5,10 @@ module Botfly
5
5
  class NickMatcher < Matcher
6
6
  def match(params)
7
7
  msg = params[:message]
8
- Botfly.logger.debug " MCH: Matching #{@condition.inspect} against #{msg.from.inspect}"
9
- Botfly.logger.debug " RESULT: #{(msg.from.node =~ @condition).inspect}"
8
+ Botfly.logger.debug "MCH: Matching #{@condition.inspect} against #{msg.from.inspect}"
9
+ Botfly.logger.debug "RESULT: #{(msg.from.node =~ @condition).inspect}"
10
10
  return msg.from.node =~ @condition
11
11
  end
12
12
  end
13
+ FromMatcher = NickMatcher
13
14
  end
@@ -5,8 +5,8 @@ module Botfly
5
5
  class SubjectMatcher < Matcher
6
6
  def match(params)
7
7
  msg = params[:message]
8
- Botfly.logger.debug " MCH: Matching #{@condition.inspect} against #{msg.subject.inspect}"
9
- Botfly.logger.debug " RESULT: #{(msg.subject =~ @condition).inspect}"
8
+ Botfly.logger.debug "MCH: Matching #{@condition.inspect} against #{msg.subject.inspect}"
9
+ Botfly.logger.debug "RESULT: #{(msg.subject =~ @condition).inspect}"
10
10
  return msg.subject.node =~ @condition
11
11
  end
12
12
  end
@@ -0,0 +1,70 @@
1
+ require 'xmpp4r/muc'
2
+
3
+ module Botfly
4
+ class MUCClient < CommonBlockAcceptor
5
+ attr_reader :bot, :muc
6
+
7
+ def room; self; end
8
+
9
+ def initialize(room, bot, &block)
10
+ super
11
+ Botfly.logger.info("MUC: New client created")
12
+ @bot = bot
13
+ @client = @bot.client
14
+ @room = room
15
+ @domain = "conference.#{@bot.jid.domain}" # A sensible default for now
16
+ @resource = @bot.jid.resource
17
+
18
+ execute(&block) if block_given? # i.e. join(room) do ... end
19
+ return self
20
+ end
21
+
22
+ def as(resource, &block)
23
+ Botfly.logger.info("MUC: as #{resource}")
24
+ @resource = resource
25
+ execute(&block) if block_given?
26
+ return self
27
+ end
28
+
29
+ def leave_room; raise "Implement Me!"; end
30
+
31
+
32
+ def respond_to(callback_type, params)
33
+ Botfly.logger.info("MUC: Got callback with time #{params[:time].inspect}")
34
+ if !params[:time].nil? # Only respond to messages from the server, if time is nil server didn't send
35
+ Botfly.logger.info("MUC: Responding to callback of type: #{callback_type} with time of #{params[:time]}")
36
+ @responders[callback_type].each {|r| r.callback_with params} if @responders[callback_type]
37
+ end
38
+ end
39
+
40
+ def to_debug_s; "MUC"; end
41
+ def class_prefix; "MUC"; end
42
+ private
43
+
44
+ def connect
45
+ Botfly.logger.info("MUC: Connecting...")
46
+ @muc = Jabber::MUC::SimpleMUCClient.new(@bot.client)
47
+ register_for_callbacks
48
+ @jid = Jabber::JID.new("#{@room}@#{@domain}/#{@resource}")
49
+ @muc.join(@jid)
50
+ Botfly.logger.info("MUC: Done connecting")
51
+ end
52
+
53
+ def execute(&block)
54
+ Botfly.logger.info("MUC: Block deteceted, executing...")
55
+ connect
56
+ instance_eval(&block)
57
+ end
58
+
59
+ def register_for_callbacks
60
+ Botfly.logger.info("MUC: Registering for MUC callbacks")
61
+ @muc.on_join {|time,nick| respond_to(:join, :time=>time,:nick=>nick)}
62
+ @muc.on_leave {|time,nick| respond_to(:leave, :time=>time,:nick=>nick)}
63
+ @muc.on_message {|time,nick,text| respond_to(:message, :time=>time,:nick=>nick,:text=>text)}
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
+ @muc.on_room_message {|time,text| respond_to(:room_message, :time => time, :text => text)}
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 => nickname, :subject => subject)}
68
+ end
69
+ end
70
+ end
@@ -1,3 +1,6 @@
1
+ require 'botfly/responder/common_responder_methods'
1
2
  require 'botfly/responder/responder'
2
3
  require 'botfly/responder/message_responder'
3
- require 'botfly/responder/presence_responder'
4
+ require 'botfly/responder/presence_responder'
5
+ require 'botfly/responder/muc_responder'
6
+ require 'botfly/responder/muc_message_responder'
@@ -0,0 +1,20 @@
1
+ module Botfly
2
+ module CommonResponderMethods
3
+ def send(nick, message, opts = {})
4
+ Botfly.logger.debug("RSP: Sending message")
5
+
6
+ # Fix the nickname if no domain/resource was given by adding your domain
7
+ nick += "@" + @bot.jid.domain if nick !~ /@.*/
8
+
9
+ opts = { :type => :chat }.merge(opts)
10
+ msg = Jabber::Message.new(nick, message)
11
+ msg.type = opts[:type]
12
+ msg.subject = opts[:subject]
13
+ @client.send(msg)
14
+ end
15
+
16
+ def remove(responder_id)
17
+ @bot.remove_responder(responder_id)
18
+ end
19
+ end
20
+ end
@@ -1,9 +1,8 @@
1
- require 'forwardable'
2
1
  module Botfly
3
2
  class MessageResponder < Responder
4
3
  extend Forwardable
5
4
  def setup_instance_variables(params)
6
- Botfly.logger.debug(" RSP: MessageResponder setting up instance variables")
5
+ Botfly.logger.debug("RSP: MessageResponder setting up instance variables")
7
6
  @message = params[:message]
8
7
  @body = @message.body
9
8
  @chat_state = @message.chat_state
@@ -14,7 +13,7 @@ module Botfly
14
13
  end
15
14
 
16
15
  def reply(text)
17
- Botfly.logger.debug(" RSP: MessageResponder#reply called")
16
+ Botfly.logger.debug("RSP: MessageResponder#reply called")
18
17
  msg = Jabber::Message.new(@from, text)
19
18
  msg.type = :chat
20
19
  @client.send(msg)
@@ -0,0 +1,4 @@
1
+ module Botfly
2
+ class MUCMessageResponder < MUCResponder
3
+ end
4
+ end
@@ -0,0 +1,68 @@
1
+ # FIXME: DRY up this and Respnoder
2
+ module Botfly
3
+ class MUCResponder < Responder
4
+ @@id = 1
5
+ extend Forwardable
6
+
7
+ def_delegator :@muc, :on
8
+ def_delegator :@bot, :client
9
+ def_delegator :@muc, :room
10
+
11
+ def initialize(muc,&block)
12
+ Botfly.logger.info("RSP: #{self.class.to_s}#new")
13
+ @matcher_chain = []
14
+ @muc = muc
15
+ @bot = @muc.bot
16
+
17
+ @callback = block if block_given?
18
+ @id = @@id += 1
19
+ end
20
+
21
+ def method_missing(method,condition,&block)
22
+ Botfly.logger.info("RSP: Responder##{method}(#{condition.inspect})")
23
+
24
+ add_matcher(method,condition)
25
+
26
+ if block_given?
27
+ Botfly.logger.info("RSP: Callback recorded: #{block.inspect}")
28
+ @callback = block
29
+ return @id
30
+ end
31
+
32
+ return self
33
+ end
34
+
35
+ def callback_with(params)
36
+ Botfly.logger.debug("RSP: Launching callback with params: #{params.inspect}")
37
+
38
+ setup_instance_variables(params)
39
+ if @matcher_chain.all? {|matcher| matcher.match(params) }
40
+ Botfly.logger.debug("RSP: All matchers passed")
41
+ cb = @callback # Ruby makes it difficult to apply & to an instance variable
42
+ instance_eval &cb
43
+ end
44
+ end
45
+
46
+ def leave #room
47
+ raise "NotImplementedError: Sorry, coming soon!"
48
+ end
49
+
50
+ def say(msg)
51
+ @muc.muc.say(msg)
52
+ end
53
+
54
+ private
55
+ def add_matcher(method, condition)
56
+ klass = Botfly.const_get("MUC" + method.to_s.capitalize + "Matcher")
57
+ @matcher_chain << klass.new(condition)
58
+
59
+ Botfly.logger.debug("RSP: Adding to matcher chain: #{@matcher_chain.inspect}")
60
+ end
61
+
62
+ def setup_instance_variables(params)
63
+ @text = @body = params[:text]
64
+ @nick = @from = params[:nick]
65
+ @time = params[:time]
66
+ end
67
+ end
68
+ end
@@ -2,6 +2,24 @@ module Botfly
2
2
  class PresenceResponder < Responder
3
3
  def setup_instance_variables(params)
4
4
  Botfly.logger.debug(" RSP: #{self.class} setting up instance variables")
5
+
6
+ # TODO: Figure out how xmpp works with presence messages so I know what to expect
7
+ if params[:new]
8
+ @presence = params[:new]
9
+ @from = @presence.from
10
+ @show = @presence.show
11
+ @priority = @presence.priority
12
+ @status = @presence.status
13
+ @type = @presence.type
14
+ end
15
+
16
+ if params[:old]
17
+ @old_presence = params[:old]
18
+ @old_status = @old_presence.status
19
+ @old_priority = @old_presence.priority
20
+ @old_type = @old_presence.type
21
+ @old_show = @old_presence.show
22
+ end
5
23
  end
6
24
  end
7
25
  end
@@ -1,13 +1,18 @@
1
1
  module Botfly
2
2
  class Responder
3
- attr_reader :callback, :callback_type
3
+ @@id = 1
4
+ include Botfly::CommonResponderMethods
5
+ extend Forwardable
6
+
7
+ attr_reader :callback, :callback_type, :id, :bot
8
+ def_delegator :@bot, :client
4
9
 
5
- def initialize(client,bot,&block)
10
+ def initialize(bot,&block)
6
11
  Botfly.logger.info(" RSP: #{self.class.to_s}#new")
7
12
  @matcher_chain = []
8
13
  @bot = bot
9
- @client = client
10
14
  @callback = block if block_given?
15
+ @id = @@id += 1
11
16
  end
12
17
 
13
18
  def method_missing(method,condition,&block)
@@ -17,7 +22,8 @@ module Botfly
17
22
 
18
23
  if block_given?
19
24
  Botfly.logger.info(" RSP: Callback recorded: #{block.inspect}")
20
- @callback = block
25
+ @callback = block
26
+ return @id
21
27
  end
22
28
 
23
29
  return self
@@ -46,14 +52,9 @@ module Botfly
46
52
 
47
53
  Botfly.logger.debug(" RSP: Adding to matcher chain: #{@matcher_chain.inspect}")
48
54
  end
49
-
50
- # TODO: Check callback is in acceptable list - MUC subclass can override this list
51
- def register_with_bot(callback_type)
52
- raise "AbstractMethodError: You must implement this method in a concrete subclass"
53
- end
54
55
 
55
56
  def setup_instance_variables(params)
56
57
  raise "AbstractMethodError: You must implement this method in a concrete subclass"
57
58
  end
58
59
  end
59
- end
60
+ end
@@ -0,0 +1,44 @@
1
+ require 'rubygems'
2
+ require 'botfly'
3
+ require 'fileutils'
4
+ require 'yaml'
5
+
6
+ config = YAML::load(ARGF.read) if ARGF
7
+
8
+ bot = Botfly.login(config["jid"],config["pass"]) do
9
+ join('lazer').as('retro-bot') do
10
+ on.message.from(/^rkneufeld/).body(/^rb count/) do
11
+ say "All votes are now being tallied. You have three votes, use them wisely"
12
+ say "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-="
13
+ room[:votes] = []
14
+ room[:votes_responder] = on.message.body(/(\d+)+/) do
15
+ @body.scan(/(\d+)+/).map {|m| room[:votes] << m.first.to_i }
16
+ end
17
+ end
18
+ on.message.from(/^rkneufeld/).body(/^rb stop count/) do
19
+ say "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-="
20
+ say "Allright, voting is finished"
21
+ remove room[:votes_responder]
22
+ sorted = room[:votes].inject({}) do |h,n|
23
+ h[n] ||= 0
24
+ h[n] += 1
25
+ h
26
+ end.sort {|a,b| b[-1] <=> a[-1] }
27
+ sorted.each {|pair| say "#{pair[0]} => #{pair[-1]} : #{room[:voted][pair[0]].person} - #{room[:voted][pair[0]].name}" }
28
+ end
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]
40
+ end
41
+ end
42
+ end
43
+
44
+ Thread.stop;loop
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
+ - 2
7
8
  - 1
8
- - 1
9
- version: 0.1.1
9
+ version: 0.2.1
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-13 00:00:00 -06:00
17
+ date: 2010-03-17 00:00:00 -05:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -54,7 +54,6 @@ extra_rdoc_files:
54
54
  - LICENSE
55
55
  - README.rdoc
56
56
  files:
57
- - .document
58
57
  - .gitignore
59
58
  - LICENSE
60
59
  - README.rdoc
@@ -64,15 +63,24 @@ files:
64
63
  - example.rb
65
64
  - lib/botfly.rb
66
65
  - lib/botfly/bot.rb
66
+ - lib/botfly/common_block_acceptor.rb
67
67
  - lib/botfly/matcher.rb
68
68
  - lib/botfly/matcher/body_matcher.rb
69
69
  - lib/botfly/matcher/matcher.rb
70
+ - lib/botfly/matcher/muc_nick_matcher.rb
71
+ - lib/botfly/matcher/muc_text_matcher.rb
72
+ - lib/botfly/matcher/muc_time_matcher.rb
70
73
  - lib/botfly/matcher/nick_matcher.rb
71
74
  - lib/botfly/matcher/subject_matcher.rb
75
+ - lib/botfly/muc_client.rb
72
76
  - lib/botfly/responder.rb
77
+ - lib/botfly/responder/common_responder_methods.rb
73
78
  - lib/botfly/responder/message_responder.rb
79
+ - lib/botfly/responder/muc_message_responder.rb
80
+ - lib/botfly/responder/muc_responder.rb
74
81
  - lib/botfly/responder/presence_responder.rb
75
82
  - lib/botfly/responder/responder.rb
83
+ - retrobot.rb
76
84
  - spec/botfly_spec.rb
77
85
  - spec/spec.opts
78
86
  - spec/spec_helper.rb
data/.document DELETED
@@ -1,5 +0,0 @@
1
- README.rdoc
2
- lib/**/*.rb
3
- bin/*
4
- features/**/*.feature
5
- LICENSE