beerbot 0.2.0.pre.1 → 0.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 87f292c599a9b6b747cf3946ba5693c3eac5e6fc
4
- data.tar.gz: 0a3a0612f3cedbb8c52508dba7cf67af4f5cae6f
3
+ metadata.gz: 7a0dc4eb8b5c748b98024c4ce5f25f0f21b8218a
4
+ data.tar.gz: 6d76393e5ef06f338e6cae31d091d00d36a4b658
5
5
  SHA512:
6
- metadata.gz: e3d16c56405388a6183dc99057dc1953c18f3df825e295ca07f4c851ddff2d3103449f89d8e56ad9a12b56fa7c3f67a0f3d53cb1ce90f088e29e5fa74107eb66
7
- data.tar.gz: 4b629d26bd44bd7a0a9e1590f07ed74f41323b3575a9415db57518a28d7c8c24d9f91a7f1163ec83bb5e7ec5a31a4715b16f23b7f172c65896c152281040cb6f
6
+ metadata.gz: 5396eca45c494e31575d230b6f16402190cd0efa80ecf6045ac0a102655318a1899d4490c2f0f1f2682186b8086a2c4ba1c2adf4dde04d9f77af77ce4b220fc0
7
+ data.tar.gz: 64f103ff21e97a574385f0fc1d07e93eed17c3732b1e3af15e9c8a06a01013d231080a5775a1540549f27edd8a1fd7d4b8d10684c246b08389f0333c819df63d
@@ -13,7 +13,14 @@
13
13
  # ruby -Ilib bin/beerbot-run-irb.rb path/to/conf.json
14
14
 
15
15
  raise "Needs ruby 2" if /^1/===RUBY_VERSION
16
- require_relative '../lib/RunIRC'
16
+ require 'beerbot'
17
+ require 'json'
18
+
19
+ Bot = BeerBot::Bot
20
+ Dispatcher = BeerBot::Dispatcher
21
+ IRCConnection = BeerBot::IRCConnection
22
+ Scheduler = BeerBot::Scheduler
23
+ codec = BeerBot::Codecs::IRC
17
24
 
18
25
  if ARGV.size == 0 then
19
26
  puts "Usage: ruby beerbot.rb path/to/ircconf.json"
@@ -21,10 +28,40 @@ if ARGV.size == 0 then
21
28
  exit 1
22
29
  end
23
30
 
31
+ # Get our configuration...
32
+
24
33
  conffile = ARGV[0]
25
34
  config = BeerBot::Config.new
26
35
  config.load JSON.load(File.read(conffile))
27
36
  config.validate!
28
37
 
29
- $runirc = BeerBot::RunIRC.new(config)
30
- $runirc.start
38
+ # Create the connection (not opened yet)...
39
+
40
+ conn = IRCConnection.new(
41
+ nick:config['nick'],
42
+ server:config['server']
43
+ )
44
+
45
+ # Create the bot.
46
+
47
+ bot = Bot.new
48
+ bot.load!(config['modules'], config['moduledir'])
49
+ config.bot = bot
50
+
51
+ # Dispatcher which handles events and messages (protocol/codec
52
+ # independent).
53
+
54
+ dispatcher = Dispatcher.new(
55
+ bot,
56
+ config['nick'],
57
+ prefix:config['cmd_prefix'],
58
+ config:config
59
+ )
60
+
61
+ # Set up scheduler.
62
+
63
+ scheduler = Scheduler.instance(config['timezone'])
64
+ config.scheduler = scheduler
65
+
66
+ $kernel = BeerBot::Kernel.new(config, conn, codec, bot, dispatcher, scheduler)
67
+ $kernel.start
@@ -6,10 +6,11 @@ require_relative 'beerbot/01.connect/IRCConnection'
6
6
  require_relative 'beerbot/01.bot/botmsg'
7
7
  require_relative 'beerbot/01.bot/BotModule'
8
8
  require_relative 'beerbot/01.bot/Bot'
9
- require_relative 'beerbot/02.protocols/irc'
10
- require_relative 'beerbot/06.dispatchers/dispatcher'
9
+ require_relative 'beerbot/02.codecs/irc'
10
+ require_relative 'beerbot/06.dispatcher'
11
11
  require_relative 'beerbot/70.scheduler/scheduler'
12
- require_relative 'beerbot/Config'
12
+ require_relative 'beerbot/config'
13
+ require_relative 'beerbot/kernel'
13
14
 
14
15
  module BeerBot
15
16
  module Modules
@@ -44,8 +44,14 @@ module BeerBot
44
44
 
45
45
  # Purge existing modules from this array and load modules with
46
46
  # names in module_names in module_path on disk into memory.
47
+ #
48
+ # MODULE NAMES and MODULE PATH:
49
+ #
50
+ # Best understood like this:
51
+ # "#{module_path}/#{name}/*" = location of modules
52
+ # modname = "::BeerBot::Modules::#{name}"
47
53
 
48
- def load! module_names,module_path
54
+ def load! module_names, module_path
49
55
  @module_path = module_path
50
56
  @module_names = module_names
51
57
  self.reject!{true} unless self.empty? # ick :)
@@ -99,9 +105,10 @@ module BeerBot
99
105
  # Call :meth on valid (loaded) modules and maybe accumulate result
100
106
  # or return first valid response...
101
107
  #
102
- # Returns array-based botmsg. The array could be empty, which
103
- # means nothing was returned (or we couldn't interpret the output
104
- # of the bot modules).
108
+ # Converts return value to ARRAY FORMAT if not already.
109
+ #
110
+ # The array could be empty, which means nothing was returned (or
111
+ # we couldn't interpret the output of the bot modules).
105
112
  #
106
113
  # We expect each bot_module to return nil or a botmsg (Hash, Array
107
114
  # or Proc that returns the first two).
@@ -5,11 +5,16 @@ module BeerBot
5
5
 
6
6
  class BotModule < Hash
7
7
  def initialize name,status:false,mod:nil,modname:nil,errors:[]
8
+
8
9
  self[:status] = status
9
- self[:name] = name # The module name.
10
- self[:mod] = mod # The loaded ruby module.
10
+
11
+ # See Bot#load!
12
+ self[:name] = name
11
13
  self[:modname] = modname
14
+ self[:mod] = mod # The loaded ruby module.
15
+
12
16
  self[:errors] = errors
17
+
13
18
  end
14
19
  end
15
20
 
@@ -100,11 +100,13 @@ module BeerBot
100
100
  end
101
101
  end
102
102
 
103
- # Transform all replies from bot modules to ARRAY FORMAT.
103
+ # Transform a botmsg (aka SINGLE RETURN FORMAT) or ARRAY FORMAT
104
+ # to ARRAY FORMAT (described below).
104
105
  #
105
- # A module may reply in either format. But we convert it here. The
106
- # single return format is the simplest, which is why we have 2
107
- # formats.
106
+ # Background:
107
+ # Bot modules may reply in either format. But we convert it
108
+ # here. The single return format is the simplest, which is why
109
+ # we have 2 formats.
108
110
  #
109
111
  # ARRAY FORMAT
110
112
  #
@@ -113,6 +115,7 @@ module BeerBot
113
115
  # where bool = true => "use <reply> and keep going"
114
116
  # = false => "use <reply> but stop here"
115
117
  # where reply = whatever the bot returns.
118
+ #
116
119
  # NOTE: any other type of array will assumed to be in
117
120
  # single return form...
118
121
  #
@@ -7,7 +7,7 @@
7
7
 
8
8
  module BeerBot
9
9
 
10
- module Protocol
10
+ module Codecs
11
11
 
12
12
  # IRC Protcol module.
13
13
  #
@@ -32,7 +32,7 @@ module BeerBot
32
32
  # Note that connection readiness and PONG protocol are handled by
33
33
  # the irc connection, not here.
34
34
 
35
- def self.parse str
35
+ def self.decode str
36
36
 
37
37
  m = IRCMessage.new(str)
38
38
  result = []
@@ -100,7 +100,7 @@ module BeerBot
100
100
  channel = m[:params][2]
101
101
  users = m[:trailing].split(/\s+/)
102
102
  result = [:chanlist,channel,users]
103
- #puts "[parse/353] #{result}"
103
+ #puts "[decode/353] #{result}"
104
104
 
105
105
  when '366' # end of 353
106
106
  result = [:chanlistend]
@@ -235,7 +235,7 @@ module BeerBot
235
235
  #
236
236
  # Generates nil if it can't handle 'botmsg'.
237
237
 
238
- def self.to_irc botmsg
238
+ def self.encode botmsg
239
239
  case botmsg
240
240
  when Hash
241
241
  to = botmsg[:to]
@@ -249,11 +249,11 @@ module BeerBot
249
249
  end
250
250
  when Array
251
251
  botmsg.map{|reply|
252
- self.to_irc reply
252
+ self.encode reply
253
253
  }
254
254
  when Proc
255
255
  #p botmsg.call
256
- self.to_irc(botmsg.call)
256
+ self.encode(botmsg.call)
257
257
  else
258
258
  nil
259
259
  end
@@ -0,0 +1,139 @@
1
+ # The files in this directory are part of BeerBot, a a ruby irc bot library.
2
+ # Copyright (C) 2013,2014 Daniel Bush
3
+ # This program is distributed under the terms of the GNU
4
+ # General Public License. A copy of the license should be
5
+ # enclosed with this project in the file LICENSE. If not
6
+ # see <http://www.gnu.org/licenses/>.
7
+
8
+ require_relative '00.utils/utils'
9
+
10
+ module BeerBot
11
+
12
+
13
+ # A dispatcher's main task is to receive incoming generic events
14
+ # (not protocol specific) and return a botmsg or empty array.
15
+ #
16
+ # This is done via the Dispatcher#receive.
17
+ #
18
+ # Dispatcher#receive takes:
19
+ # 1) event - a symbol representing an event eg :msg, :join etc
20
+ # 2) args - an array representing arguments
21
+ # 'event' and 'args' are intended to be protocol-neutral.
22
+ #
23
+ # This class is basically a glorified struct with a receive method
24
+ # that is the default way to dispatch to an instance of Bot.
25
+ #
26
+ # You have several options if you want to customize...
27
+ # 1) subclass if you want to pre or post filter
28
+ # 2) override #receive with your own singleton receive (see tests)
29
+ # 3) make a new Dispatcher-like class
30
+
31
+ class Dispatcher
32
+
33
+ Utils = BeerBot::Utils
34
+ BotMsg = BeerBot::BotMsg
35
+
36
+ attr_accessor :bot,:nick,:prefix,:config
37
+
38
+ def initialize bot,nick,prefix:',',config:nil
39
+ @bot = bot
40
+ @nick = nick
41
+ @prefix = prefix
42
+ @config = config
43
+ @get_nick_cmd = Utils.make_prefix_parser(nick)
44
+ @nickrx = Regexp.new("^#{nick}$",'i')
45
+ @get_prefix_cmd = Utils.make_prefix_parser(prefix)
46
+ end
47
+
48
+ # Receive generic events emitted by a protocol class and
49
+ # dispatch to an instance of Bot.
50
+ #
51
+ # eg the output from BeerBot::Codecs::IRC.decode .
52
+
53
+ def receive event,args
54
+
55
+ replies = nil
56
+
57
+ # Otherwise, here is the default behaviour...
58
+
59
+ case event
60
+ when :unknown
61
+ replies = @bot.event(event,args:args,config:@config)
62
+ when :default
63
+ replies = @bot.event(event,args:args,config:@config)
64
+
65
+ when :nick
66
+ old,nick = args
67
+ replies = @bot.event(event,old:old,nick:nick,config:@config)
68
+
69
+ when :quit
70
+ nick,msg = args
71
+ replies = @bot.event(event,nick:nick,msg:msg,config:@config)
72
+ when :part
73
+ nick,channel = args
74
+ replies = @bot.event(event,nick:nick,channel:channel,config:@config)
75
+ when :join
76
+ nick,channel = args
77
+ me = (@nickrx === nick)
78
+ replies = @bot.event(event,me:me,nick:nick,channel:channel,config:@config)
79
+ when :chanlist
80
+ channel,users = args
81
+ replies = @bot.event(event,channel:channel,users:users,config:@config)
82
+ when :chanlistend
83
+ # ignore
84
+
85
+ when :action
86
+ from,to,action = args
87
+ me = (@nickrx === to)
88
+ replies = @bot.action(action,from:from,to:to,me:me,config:@config)
89
+
90
+ when :msg
91
+ from,to,msg = args
92
+
93
+ # Somebody messaging us privately:
94
+ me = (@nickrx === to)
95
+
96
+ # Somebody talking to us on channel: "Beerbot: ..."
97
+ cmd = @get_nick_cmd.call(msg)
98
+ if not cmd then
99
+ # Somebody commanding us on channel: ",command ..."
100
+ cmd = @get_prefix_cmd.call(msg)
101
+ end
102
+
103
+ if cmd then
104
+ case cmd
105
+ # dispatch help...
106
+ when /^\s*help(?:\s+(.*))?$/
107
+ if $1.nil? then
108
+ args = []
109
+ else
110
+ args = $1.strip.split(/\s+/)
111
+ end
112
+ replies = @bot.help(args,from:from,to:to,me:me,config:@config)
113
+ # dispatch cmd...
114
+ else
115
+ replies = @bot.cmd(cmd,from:from,to:to,me:me,config:@config)
116
+ end
117
+ else
118
+ # We're just hearing something on a channel...
119
+ replies = @bot.hear(msg,from:from,to:to,me:me,config:@config)
120
+ end
121
+
122
+ else
123
+ puts "[dispatcher] unrecognised event: '#{event}'"
124
+ end
125
+
126
+ case replies
127
+ when String # assume protocol string eg irc
128
+ replies
129
+ when Hash,Array,Proc
130
+ BotMsg.to_a(replies)
131
+ else
132
+ []
133
+ end
134
+
135
+ end
136
+
137
+ end
138
+
139
+ end
@@ -7,6 +7,9 @@
7
7
 
8
8
  module BeerBot
9
9
  module Scheduler
10
+
11
+ CronR = ::CronR
12
+
10
13
  def self.instance timezone=nil
11
14
  @instance ||= CronR::Cron.new
12
15
  if timezone then
@@ -14,5 +17,6 @@ module BeerBot
14
17
  end
15
18
  @instance
16
19
  end
20
+
17
21
  end
18
22
  end
@@ -43,7 +43,9 @@ module BeerBot
43
43
  # Defaults
44
44
  self['cmd_prefix'] = ','
45
45
  self['nick'] = 'beerbot'
46
- self.merge(kargs)
46
+ kargs.keys.each {|key|
47
+ self[key.to_s] = kargs[key]
48
+ }
47
49
  end
48
50
 
49
51
  def load config
@@ -9,29 +9,27 @@ require 'set'
9
9
  require 'rubygems'
10
10
  require 'pry'
11
11
  require 'json'
12
- require_relative 'beerbot'
13
12
 
14
- # Run the irc bot.
13
+ require_relative '00.utils/utils'
14
+ require_relative '00.utils/InOut'
15
+ require_relative '01.bot/botmsg'
16
+
17
+ # Run the bot.
15
18
  #
16
19
  # This class creates and coordinates all the high level components
17
- # needed to run beerbot over irc.
20
+ # needed to run beerbot.
18
21
  #
19
22
  # See bin/* .
20
23
 
21
24
  module BeerBot; end
22
25
 
23
- class BeerBot::RunIRC
26
+ class BeerBot::Kernel
24
27
 
25
28
  Utils = BeerBot::Utils
26
29
  InOut = BeerBot::Utils::InOut
27
- IRCConnection = BeerBot::IRCConnection
28
- IRC = BeerBot::Protocol::IRC
29
- Bot = BeerBot::Bot
30
30
  BotMsg = BeerBot::BotMsg
31
- Dispatcher = BeerBot::Dispatchers::Dispatcher
32
- Scheduler = BeerBot::Scheduler
33
31
 
34
- attr_accessor :config,:bot,:scheduler,:dispatcher,:conn,:postq,:parse,:more
32
+ attr_accessor :config, :bot, :scheduler, :dispatcher, :conn, :codec
35
33
 
36
34
  # Initialize all parts of the system here.
37
35
  #
@@ -39,43 +37,27 @@ class BeerBot::RunIRC
39
37
  #
40
38
  # Note BeerBot::Config should be loaded before we initialize here.
41
39
 
42
- def initialize config
40
+ def initialize config, conn, codec, bot, dispatcher, scheduler
43
41
 
44
42
  @echo = true
45
43
  @path = File.expand_path(File.dirname(__FILE__)+'/..')
46
44
  @module_path = config['moduledir']
47
45
  @config = config
46
+ @bot = bot
47
+ @conn = conn
48
+ @codec = codec
49
+ @dispatcher = dispatcher
50
+ @scheduler = scheduler
51
+
48
52
 
49
- # Create the bot.
50
- @bot = Bot.new
51
- @bot.load!(config['modules'],@module_path)
52
- config.bot = @bot
53
-
54
- # Dispatcher which receives messages and interacts with the bot.
55
- @dispatcher = Dispatcher.new(
56
- @bot,
57
- config['nick'],
58
- prefix:config['cmd_prefix'],
59
- config:config
60
- )
61
-
62
- # Set up scheduler (this doesn't start it yet)...
63
- @scheduler = Scheduler.instance(config['timezone'])
64
- config.scheduler = @scheduler
65
-
66
- # Create but don't open the irc connection.
67
- @conn = IRCConnection.new(
68
- nick:config['nick'],
69
- server:config['server'])
70
-
71
- # Dispatcher thread takes stuff coming from the irc connection and does
53
+ # Dispatcher thread takes stuff coming from the connection and does
72
54
  # something with it...
73
55
 
74
56
  @dispatcher_thread = InOut.new(inq:@conn.queue,outq:@conn.writeq) {|input|
75
57
  str,raw = input
76
- event,*args = IRC.parse(str)
58
+ event,*args = @codec.decode(str)
77
59
  replies = @dispatcher.receive(event,args)
78
- IRC.to_irc(replies)
60
+ @codec.encode(replies)
79
61
  }
80
62
  @dispatcher_thread.start!
81
63
 
@@ -87,7 +69,7 @@ class BeerBot::RunIRC
87
69
  @scheduler_thread = InOut.new(inq:@scheduler.queue,outq:@conn.writeq) {|cron_job|
88
70
  puts "<< scheduler #{cron_job.inspect}" if @echo
89
71
  puts "<< scheduler #{@scheduler.time}" if @echo
90
- IRC.to_irc(cron_job.run)
72
+ @codec.encode(cron_job.run)
91
73
  }
92
74
  @scheduler_thread.start!
93
75
 
@@ -104,7 +86,7 @@ class BeerBot::RunIRC
104
86
  when String # assume protocol string eg irc
105
87
  replies
106
88
  when Hash,Array,Proc
107
- IRC.to_irc(BotMsg.to_a(replies))
89
+ @codec.encode(BotMsg.to_a(replies))
108
90
  else
109
91
  []
110
92
  end
@@ -114,18 +96,20 @@ class BeerBot::RunIRC
114
96
  # Set up a repl in a separate thread.
115
97
  #
116
98
  # In pry, you can then do:
117
- # @conn.writeq.enq IRC.join('#chan1')
118
- # @conn.write IRC.join('#chan1')
99
+ # @conn.writeq.enq @codec.join('#chan1')
100
+ # @conn.write @codec.join('#chan1')
119
101
 
120
102
  Pry.config.prompt = Proc.new {|_| "pry> "}
121
103
  @pry_thread = Thread.new {
122
104
  binding.pry
123
105
  }
124
106
 
107
+ # Initialize bot and its modules...
108
+
125
109
  @bot.init(@config)
126
110
  @bot.update_config(@config)
127
111
 
128
- # Do stuff once we've identified with the irc server...
112
+ # Do stuff once we've identified with the server...
129
113
  #
130
114
  # Join channels.
131
115
  # Start the scheduler.
@@ -159,25 +143,25 @@ class BeerBot::RunIRC
159
143
  # Convenience method to say something to channel or someone.
160
144
 
161
145
  def say to,msg
162
- @conn.writeq.enq(IRC.msg(to,msg))
146
+ @conn.writeq.enq(@codec.msg(to,msg))
163
147
  end
164
148
 
165
149
  # Convenience method to do something (/me).
166
150
 
167
151
  def action to,msg
168
- @conn.writeq.enq(IRC.action(to,msg))
152
+ @conn.writeq.enq(@codec.action(to,msg))
169
153
  end
170
154
 
171
155
  # Convenience method to join a channel.
172
156
 
173
157
  def join chan
174
- @conn.writeq.enq(IRC.join(chan))
158
+ @conn.writeq.enq(@codec.join(chan))
175
159
  end
176
160
 
177
161
  # Convenience method to leave a channel.
178
162
 
179
163
  def leave chan
180
- @conn.writeq.enq(IRC.leave(chan))
164
+ @conn.writeq.enq(@codec.leave(chan))
181
165
  end
182
166
 
183
167
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: beerbot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0.pre.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Bush
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-04 00:00:00.000000000 Z
11
+ date: 2014-09-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pry
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - '='
46
46
  - !ruby/object:Gem::Version
47
- version: 0.1.4
47
+ version: 0.1.5
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - '='
53
53
  - !ruby/object:Gem::Version
54
- version: 0.1.4
54
+ version: 0.1.5
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rspec
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -94,12 +94,12 @@ files:
94
94
  - lib/beerbot/01.bot/BotModule.rb
95
95
  - lib/beerbot/01.bot/botmsg.rb
96
96
  - lib/beerbot/01.bot/Bot.rb
97
- - lib/beerbot/02.protocols/irc.rb
98
- - lib/beerbot/06.dispatchers/dispatcher.rb
97
+ - lib/beerbot/02.codecs/irc.rb
98
+ - lib/beerbot/06.dispatcher.rb
99
99
  - lib/beerbot/70.scheduler/scheduler.rb
100
- - lib/beerbot/Config.rb
100
+ - lib/beerbot/config.rb
101
+ - lib/beerbot/kernel.rb
101
102
  - lib/beerbot.rb
102
- - lib/RunIRC.rb
103
103
  - bin/beerbot-run-irc.rb
104
104
  homepage: http://github.com/danielbush/BeerBot
105
105
  licenses:
@@ -116,13 +116,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
116
116
  version: '0'
117
117
  required_rubygems_version: !ruby/object:Gem::Requirement
118
118
  requirements:
119
- - - '>'
119
+ - - '>='
120
120
  - !ruby/object:Gem::Version
121
- version: 1.3.1
121
+ version: '0'
122
122
  requirements: []
123
123
  rubyforge_project:
124
124
  rubygems_version: 2.1.10
125
125
  signing_key:
126
126
  specification_version: 4
127
- summary: An ruby 2.0 bot
127
+ summary: A ruby 2.0 bot
128
128
  test_files: []
@@ -1,139 +0,0 @@
1
- # The files in this directory are part of BeerBot, a a ruby irc bot library.
2
- # Copyright (C) 2013,2014 Daniel Bush
3
- # This program is distributed under the terms of the GNU
4
- # General Public License. A copy of the license should be
5
- # enclosed with this project in the file LICENSE. If not
6
- # see <http://www.gnu.org/licenses/>.
7
-
8
- require_relative '../00.utils/utils'
9
-
10
- module BeerBot
11
-
12
- # Dispatchers receive incoming messages from a protocol object and
13
- # dispatches them (usually to an instance of Bot).
14
- #
15
- # Dispatcher#receive takes:
16
- # 1) event - a symbol representing an event eg :msg, :join etc
17
- # 2) args - an array representing arguments
18
-
19
- module Dispatchers
20
-
21
- # This class is basically a glorified struct with a receive method
22
- # that is the default way to dispatch to an instance of Bot.
23
- #
24
- # You have several options if you want to customize...
25
- # 1) subclass if you want to pre or post filter
26
- # 2) override #receive with your own singleton receive (see tests)
27
- # 3) make a new Dispatcher-like class
28
-
29
- class Dispatcher
30
-
31
- Utils = BeerBot::Utils
32
- BotMsg = BeerBot::BotMsg
33
-
34
- attr_accessor :bot,:nick,:prefix,:config
35
-
36
- def initialize bot,nick,prefix:',',config:nil
37
- @bot = bot
38
- @nick = nick
39
- @prefix = prefix
40
- @config = config
41
- @get_nick_cmd = Utils.make_prefix_parser(nick)
42
- @nickrx = Regexp.new("^#{nick}$",'i')
43
- @get_prefix_cmd = Utils.make_prefix_parser(prefix)
44
- end
45
-
46
- # Receive generic events emitted by a protocol class and
47
- # dispatch to an instance of Bot.
48
- #
49
- # eg the output from BeerBot::Protocol::IRC.parse .
50
-
51
- def receive event,args
52
-
53
- replies = nil
54
-
55
- # Otherwise, here is the default behaviour...
56
-
57
- case event
58
- when :unknown
59
- replies = @bot.event(event,args:args,config:@config)
60
- when :default
61
- replies = @bot.event(event,args:args,config:@config)
62
-
63
- when :nick
64
- old,nick = args
65
- replies = @bot.event(event,old:old,nick:nick,config:@config)
66
-
67
- when :quit
68
- nick,msg = args
69
- replies = @bot.event(event,nick:nick,msg:msg,config:@config)
70
- when :part
71
- nick,channel = args
72
- replies = @bot.event(event,nick:nick,channel:channel,config:@config)
73
- when :join
74
- nick,channel = args
75
- me = (@nickrx === nick)
76
- replies = @bot.event(event,me:me,nick:nick,channel:channel,config:@config)
77
- when :chanlist
78
- channel,users = args
79
- replies = @bot.event(event,channel:channel,users:users,config:@config)
80
- when :chanlistend
81
- # ignore
82
-
83
- when :action
84
- from,to,action = args
85
- me = (@nickrx === to)
86
- replies = @bot.action(action,from:from,to:to,me:me,config:@config)
87
-
88
- when :msg
89
- from,to,msg = args
90
-
91
- # Somebody messaging us privately:
92
- me = (@nickrx === to)
93
-
94
- # Somebody talking to us on channel: "Beerbot: ..."
95
- cmd = @get_nick_cmd.call(msg)
96
- if not cmd then
97
- # Somebody commanding us on channel: ",command ..."
98
- cmd = @get_prefix_cmd.call(msg)
99
- end
100
-
101
- if cmd then
102
- case cmd
103
- # dispatch help...
104
- when /^\s*help(?:\s+(.*))?$/
105
- if $1.nil? then
106
- args = []
107
- else
108
- args = $1.strip.split(/\s+/)
109
- end
110
- replies = @bot.help(args,from:from,to:to,me:me,config:@config)
111
- # dispatch cmd...
112
- else
113
- replies = @bot.cmd(cmd,from:from,to:to,me:me,config:@config)
114
- end
115
- else
116
- # We're just hearing something on a channel...
117
- replies = @bot.hear(msg,from:from,to:to,me:me,config:@config)
118
- end
119
-
120
- else
121
- puts "[dispatcher] unrecognised event: '#{event}'"
122
- end
123
-
124
- case replies
125
- when String # assume protocol string eg irc
126
- replies
127
- when Hash,Array,Proc
128
- BotMsg.to_a(replies)
129
- else
130
- []
131
- end
132
-
133
- end
134
-
135
- end
136
-
137
- end
138
-
139
- end