botfly 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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