class BeerBot::Bot
Represents a sequence of BotModule
instances.
Attributes
Public Class Methods
# File lib/beerbot/01.bot/Bot.rb, line 19 def initialize super() end
Public Instance Methods
# File lib/beerbot/01.bot/Bot.rb, line 158 def action action,from:nil,to:nil,me:false,config:nil self.run(:action,action,from:from,to:to,me:me,config:config) end
Process messages addressed directly to the bot.
# File lib/beerbot/01.bot/Bot.rb, line 140 def cmd msg,from:nil,to:nil,me:false,config:nil if @cmd then @cmd.call(msg,from:from,to:to,config:config,me:me) else self.run(:cmd,msg,from:from,to:to,config:config,me:me) end end
Handle events other than being messaged.
IRC events like joining channels, changing nicks etc.
Both event and kargs is dependent on the dispatcher which in turn is dependent on how the protocol (eg irc) is parsed.
# File lib/beerbot/01.bot/Bot.rb, line 169 def event event,**kargs self.run(:event,event,**kargs) end
# File lib/beerbot/01.bot/Bot.rb, line 91 def has_errors if self.find{|bot_module| !bot_module[:status]} then true else false end end
Process messages the bot overhears.
# File lib/beerbot/01.bot/Bot.rb, line 150 def hear msg,from:nil,to:nil,me:false,config:nil if @hear then @hear.call(msg,from:from,to:to,me:me,config:config) else self.run(:hear,msg,from:from,to:to,me:me,config:config) end end
# File lib/beerbot/01.bot/Bot.rb, line 173 def help arr,from:nil,to:nil,config:nil,me:false m = [] modname,*topics = arr # "help" if arr.empty? then helplist = self.valid_modules.select {|bot_module| bot_module[:mod].respond_to?(:help) }.map{|bot_module| bot_module[:name] } reply = [ { to:from, msg:"To issue commands to the bot over a channel, you need to start with a command prefix like ','." }, { to:from, msg:"Modules (type: help <module-name>): "+helplist.join('; ') } ] # "help modname [subtopic [... [... etc]]]" else bot_module = self.valid_modules.find{|bot_module| bot_module[:name]==modname } # Can't find module... if bot_module.nil? then reply = [to:to,msg:"Don't know this topic #{from}"] # Can find module... else mod = bot_module[:mod] reply = [] # Module has help... if mod.respond_to?(:help) then arr = mod.help(topics) if !arr || arr.empty? then reply += [to:from,msg:"hmmm, the module didn't say anything..."] else if topics.empty? then reply += [to:from,msg:"Note: modules should list topics which you can access like: help #{modname} <topic>"] end reply += arr.map{|a| {to:from,msg:a}} end # Module doesn't have help... else reply += [to:from,msg:"type: #{modname} doesn't seem to have any help"] end end end if not me then reply += [to:to,msg:"pm'ing you #{from}"] end return reply end
Call all init methods on bot modules that have them.
Should only be called once.
# File lib/beerbot/01.bot/Bot.rb, line 27 def init config self.valid_modules.each {|botmodule| if botmodule[:mod].respond_to?(:init) then botmodule[:mod].init(config) end } end
Purge existing modules from this array and load modules with names in module_names
in module_path
on disk into memory.
MODULE NAMES and MODULE PATH:
Best understood like this:
"#{module_path}/#{name}/*" = location of modules modname = "::BeerBot::Modules::#{name}"
# File lib/beerbot/01.bot/Bot.rb, line 54 def load! module_names, module_path @module_path = module_path @module_names = module_names self.reject!{true} unless self.empty? # ick :) Dir.chdir(module_path) { module_names.each {|name| initfile = "#{name}/init.rb" modname = "::BeerBot::Modules::#{name}" mod = nil err = [ [:nodir,!File.directory?(name)], [:badname,name !~ /^[A-Z]/ ], [:noinit,!File.exists?(initfile)], ].select{|e| e[1]} ok = (err.size == 0) if ok then puts "loading #{initfile}..." load(initfile) mod = Object.const_get(modname) if mod.respond_to?(:instance) then mod = mod.instance end else p [initfile,err] raise "Can't load (some) modules." end bm = BotModule.new( name,status:ok,mod:mod, modname:modname,errors:err ) self.push(bm) } } end
Call :meth on valid (loaded) modules and maybe accumulate result or return first valid response…
Converts return value to ARRAY FORMAT if not already.
The array could be empty, which means nothing was returned (or we couldn’t interpret the output of the bot modules).
We expect each bot_module to return nil or a botmsg (Hash, Array or Proc that returns the first two).
At the moment, we use inject and break on first valid response…
# File lib/beerbot/01.bot/Bot.rb, line 119 def run meth,*args,**kargs self.valid_modules.inject([]) {|arr,bot_module| name,mod = bot_module.values_at(:name,:mod) unless mod.respond_to?(meth) then next arr end reply = mod.send(meth,*args,**kargs) suppress,botmsg = BotMsg.to_reply_format(reply) if botmsg then arr += botmsg end if suppress then break arr else arr end } end
Override normal cmd processing with Proc.
You might want to do this to temporarily stop normal bot command behaviour in order for the bot to go into some sort of exclusive mode.
To disable normal response behaviour do:
bot.set_cmd {|msg,**kargs| nil } bot.set_hear {|msg,**kargs| nil }
To unset,
bot.set_cmd bot.set_hear
# File lib/beerbot/01.bot/Bot.rb, line 258 def set_cmd &block @cmd = block end
Override normal hear-processing with Proc.
See set_cmd.
# File lib/beerbot/01.bot/Bot.rb, line 266 def set_hear &block @hear = block end
Call config on all valid bot modules.
# File lib/beerbot/01.bot/Bot.rb, line 37 def update_config config self.valid_modules.each {|botmodule| if botmodule[:mod].respond_to?(:config) then botmodule[:mod].config(config) end } end
Return list of valid (loaded) modules.
# File lib/beerbot/01.bot/Bot.rb, line 101 def valid_modules self.select{|bot_module| bot_module[:status]} end