Class: Marvin::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/marvin/base.rb

Overview

A Client Handler

Direct Known Subclasses

CommandHandler

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeBase

Returns a new instance of Base.



15
16
17
18
# File 'lib/marvin/base.rb', line 15

def initialize
  self.registered_handlers ||= {}
  self.logger ||= Marvin::Logger
end

Instance Attribute Details

#clientObject

Returns the value of attribute client.



11
12
13
# File 'lib/marvin/base.rb', line 11

def client
  @client
end

#fromObject

Returns the value of attribute from.



11
12
13
# File 'lib/marvin/base.rb', line 11

def from
  @from
end

#loggerObject

Returns the value of attribute logger.



11
12
13
# File 'lib/marvin/base.rb', line 11

def logger
  @logger
end

#optionsObject

Returns the value of attribute options.



11
12
13
# File 'lib/marvin/base.rb', line 11

def options
  @options
end

#targetObject

Returns the value of attribute target.



11
12
13
# File 'lib/marvin/base.rb', line 11

def target
  @target
end

Class Method Details

.event_handlers_for(message_name, direct = true) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/marvin/base.rb', line 22

def event_handlers_for(message_name, direct = true)
  return [] if self == Marvin::Base
  rh = (self.registered_handlers ||= {})
  rh[self.name] ||= {}
  rh[self.name][message_name] ||= []
  if direct
    found_handlers = rh[self.name][message_name]
    found_handlers += self.superclass.event_handlers_for(message_name)
    return found_handlers
  else
    return rh[self.name][message_name]
  end
end

.on_event(name, method_name = nil, &blk) ⇒ Object

Registers a block or method to be called when a given event is occured.

Examples

on_event :incoming_message, :process_commands

Will call process_commands the current object every time incoming message is called.

on_event :incoming_message do
  Marvin::Logger.debug ">> #{options.inspect}"
end

Will invoke the block every time an incoming message is processed.



51
52
53
54
55
56
# File 'lib/marvin/base.rb', line 51

def on_event(name, method_name = nil, &blk)
  # If the name is set and it responds to :to_sym
  # and no block was passed in.
  blk = proc { self.send(method_name.to_sym) } if method_name.respond_to?(:to_sym) && blk.blank?
  self.event_handlers_for(name, false) << blk
end

.on_numeric(value, method_name = nil, &blk) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/marvin/base.rb', line 58

def on_numeric(value, method_name = nil, &blk)
  if value.is_a?(Numeric)
    new_value = "%03d" % value
  else
    new_value = Marvin::IRC::Replies[value]
  end
  if new_value.nil?
    logger.error "The numeric '#{value}' was undefined"
  else
    blk = proc { self.send(method_name.to_sym) } if method_name.respond_to?(:to_sym) && blk.blank?
    self.event_handlers_for(:"incoming_numeric_#{new_value}", false) << blk
  end
end

.register!(parent = Marvin::Settings.default_client) ⇒ Object

Register’s in the IRC Client callback chain.



73
74
75
76
# File 'lib/marvin/base.rb', line 73

def register!(parent = Marvin::Settings.default_client)
  return if self == Marvin::Base # Only do it for sub-classes.
  parent.register_handler self.new
end

.uses_datastore(datastore_name, local_name) ⇒ Object



78
79
80
81
82
83
# File 'lib/marvin/base.rb', line 78

def uses_datastore(datastore_name, local_name)
  cattr_accessor local_name.to_sym
  self.send("#{local_name}=", Marvin::DataStore.new(datastore_name))
  rescue Exception => e
    logger.debug "Exception in datastore declaration - #{e.inspect}"
end

Instance Method Details

#addressed?Boolean

Returns:

  • (Boolean)


141
142
143
# File 'lib/marvin/base.rb', line 141

def addressed?
  self.from_user? || options.message =~ /^#{self.client.nickname.downcase}:\s+/i
end

#ctcp(message) ⇒ Object



123
124
125
126
# File 'lib/marvin/base.rb', line 123

def ctcp(message)
  return if from_channel? # Must be from user
  say "\01#{message}\01", self.from
end

#from_channel?Boolean

Determines whether the previous message was inside a channel.

Returns:

  • (Boolean)


137
138
139
# File 'lib/marvin/base.rb', line 137

def from_channel?
  self.target && [?#, ?&].include?(self.target[0])
end

#from_user?Boolean

reflects whether or not the current message / previous message came from a user via pm.

Returns:

  • (Boolean)


132
133
134
# File 'lib/marvin/base.rb', line 132

def from_user?
  self.target && !from_channel?
end

#halt!Object

Halt’s on the handler, used to prevent other handlers also responding to the same message more than once.



154
155
156
# File 'lib/marvin/base.rb', line 154

def halt!
  raise HaltHandlerProcessing
end

#handle(message, options) ⇒ Object

Given an incoming message, handle it appropriatly.



88
89
90
91
92
93
94
95
96
97
# File 'lib/marvin/base.rb', line 88

def handle(message, options)
  begin
    self.setup_defaults(options)
    h = self.class.event_handlers_for(message)
    h.each { |handle| self.instance_eval(&handle) }
  rescue Exception => e
    logger.fatal "Exception processing handle #{message}"
    Marvin::ExceptionTracker.log(e)
  end
end

#handle_incoming_numeric(opts) ⇒ Object



99
100
101
102
103
104
105
# File 'lib/marvin/base.rb', line 99

def handle_incoming_numeric(opts)
  self.handle(:incoming_numeric, opts)
  name = :"incoming_numeric_#{options.code}"
  events = self.class.event_handlers_for(name)
  logger.debug "Dispatching #{events.size} events for #{name}"
  events.each { |eh| self.instance_eval(&eh) }
end

#pm(target, message) ⇒ Object



111
112
113
# File 'lib/marvin/base.rb', line 111

def pm(target, message)
  say(target, message)
end

#reply(message) ⇒ Object



115
116
117
118
119
120
121
# File 'lib/marvin/base.rb', line 115

def reply(message)
  if from_channel?
    say "#{self.from}: #{message}"
  else
    say message, self.from # Default back to pm'ing the user
  end
end

#say(message, target = self.target) ⇒ Object



107
108
109
# File 'lib/marvin/base.rb', line 107

def say(message, target = self.target)
  client.msg target, message
end

#setup_defaults(options) ⇒ Object



145
146
147
148
149
# File 'lib/marvin/base.rb', line 145

def setup_defaults(options)
  self.options = options.is_a?(OpenStruct) ? options : OpenStruct.new(options)
  self.target  = options[:target] if options.has_key?(:target)
  self.from    = options[:nick]   if options.has_key?(:nick)
end