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 CHANGED
@@ -1 +1 @@
1
- 0.2.1
1
+ 0.3.0
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{botfly}
8
- s.version = "0.2.1"
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-17}
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",
@@ -2,8 +2,7 @@ require 'rubygems'
2
2
 
3
3
  require 'xmpp4r'
4
4
  require 'xmpp4r/muc'
5
- require 'forwardable'
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
@@ -2,51 +2,58 @@ require 'rubygems'
2
2
 
3
3
  module Botfly
4
4
  class Bot < CommonBlockAcceptor
5
- attr_reader :jid
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
- "BOT"
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
- # @client.add_subscription_request_callback {|item, pres| } # requires Roster helper
45
- @client.add_message_callback do |message|
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
- @client.add_presence_callback do |new_presence,old_presence|
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("BOT: Removing responder #{id_to_remove}")
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
 
@@ -7,5 +7,6 @@ module Botfly
7
7
  def match(params)
8
8
  raise "AbstractMethodError: You must implement match in a concrete subclass"
9
9
  end
10
+
10
11
  end
11
12
  end
@@ -4,7 +4,7 @@ module Botfly
4
4
  class MUCClient < CommonBlockAcceptor
5
5
  attr_reader :bot, :muc
6
6
 
7
- def room; self; end
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.resource
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
- 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
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 => nickname, :subject => subject)}
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,condition,&block)
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
@@ -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(/^rb count/) do
11
- say "All votes are now being tallied. You have three votes, use them wisely"
12
- say "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-="
13
- room[:votes] = []
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 {|m| room[:votes] << m.first.to_i }
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(/^rb stop count/) do
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
- 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]
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
- - 2
8
- - 1
9
- version: 0.2.1
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 00:00:00 -05:00
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