Class: Marvin::Base

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

Direct Known Subclasses

CommandHandler, Distributed::Handler

Constant Summary

@@handlers =
Hash.new do |h,k|
  h[k] = Hash.new { |h2, k2| h2[k2] = [] }
end

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#clientObject

Returns the value of attribute client



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

def client
  @client
end

#fromObject

Returns the value of attribute from



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

def from
  @from
end

#optionsObject

Returns the value of attribute options



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

def options
  @options
end

#targetObject

Returns the value of attribute target



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

def target
  @target
end

Class Method Details

.event_handlers_for(message_name) ⇒ Object

Returns an array of all handlers associated with a specific event name (e.g. :incoming_message)



30
31
32
33
34
35
36
37
38
39
# File 'lib/marvin/base.rb', line 30

def event_handlers_for(message_name)
  message_name = message_name.to_sym
  items = []
  klass = self
  while klass != Object
    items += @@handlers[klass][message_name]
    klass = klass.superclass
  end
  items
end

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

Registers a block to be used as an event handler. The first argument is always the name of the event and the second is either a method name (e.g. :my_awesome_method) or a block (which is instance_evaled)



45
46
47
48
# File 'lib/marvin/base.rb', line 45

def on_event(name, method_name = nil, &blk)
  blk = proc { self.send(method_name) } if method_name.present?
  @@handlers[self][name] << blk
end

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

Like on_event but instead of taking an event name it takes either a number or a name - corresponding to an IRC numeric reply.



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

def on_numeric(value, method_name = nil, &blk)
  value = value.is_a?(Numeric) ? ("%03d" % value) : Marvin::IRC::Replies[value]
  on_event(:incoming_numeric_#{new_value}", method_name, &blk) if value.present?
end

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

Register this specific handler on the IRC handler.



59
60
61
62
63
# File 'lib/marvin/base.rb', line 59

def register!(parent = Marvin::Settings.client)
  return if self == Marvin::Base # Only do it for sub-classes.
  parent.register_handler self.new unless parent.handlers.any? { |h| h.class == self }
  Marvin.handler_parent_classes[self.name] << parent
end

.registered=(value) ⇒ Object



24
25
26
# File 'lib/marvin/base.rb', line 24

def registered=(value)
  @registered = !!value
end

.registered?Boolean



20
21
22
# File 'lib/marvin/base.rb', line 20

def registered?
  @registered ||= false
end

.reloaded!Object



76
77
78
79
80
81
82
83
84
85
86
# File 'lib/marvin/base.rb', line 76

def reloaded!
  Marvin.handler_parent_classes[self.name].each do |dispatcher|
    before = dispatcher.handlers
    register!(dispatcher)
    after = dispatcher.handlers
    (after - before).each do |h|
      h.client = dispatcher
      h.handle(:reloaded, {})
    end
  end
end

.reloading!Object



65
66
67
68
69
70
71
72
73
74
# File 'lib/marvin/base.rb', line 65

def reloading!
  Marvin.handler_parent_classes[self.name].each do |dispatcher|
    parent_handlers = dispatcher.handlers
    related = parent_handlers.select { |h| h.class == self }
    related.each do |h|
      h.handle(:reloading, {})
      dispatcher.delete_handler(h)
    end
  end
end

Instance Method Details

#_handle(message, options) ⇒ Object

Given an incoming message, handle it appropriately by getting all associated event handlers. It also logs any exceptions (aslong as they raised by halt)



97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/marvin/base.rb', line 97

def _handle(message, options)
  setup_details(options)
  h = self.class.event_handlers_for(message)
  h.each { |eh| self.instance_eval(&eh) }
rescue Exception => e
  # Pass on halt_handler_processing events.
  raise e if e.is_a?(Marvin::HaltHandlerProcessing)
  logger.fatal "Exception processing handler for #{message.inspect}"
  Marvin::ExceptionTracker.log(e)
ensure
  reset_details
end

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



126
127
128
# File 'lib/marvin/base.rb', line 126

def action(message, target = self.target)
  client.action(target, message)
end

#addressed?Boolean



165
166
167
# File 'lib/marvin/base.rb', line 165

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

#ctcp(message) ⇒ Object



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

def ctcp(message)
  say("\01#{message}\01", from) if !from_channel?
end

#from_channel?(target = self.target) ⇒ Boolean

Determines whether a given target (defaulting to the target of the last message was in a channel)



161
162
163
# File 'lib/marvin/base.rb', line 161

def from_channel?(target = self.target)
  target.present? && target =~ /^[\&\#]/
end

#from_user?Boolean

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



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

def from_user?
  !from_channel?
end

#handle(message, options) ⇒ Object



90
91
92
# File 'lib/marvin/base.rb', line 90

def handle(message, options)
  dup._handle(message, options)
end

#handle_incoming_numeric(opts) ⇒ Object

The default handler for numerics. mutates them into a more friendly version of themselves. It will also pass through the original incoming_numeric event.



113
114
115
116
# File 'lib/marvin/base.rb', line 113

def handle_incoming_numeric(opts)
  handle(:incoming_numeric, opts)
  handle(:incoming_numeric_#{opts[:code]}", opts)
end

#msg(message, target = self.target) ⇒ Object Also known as: say

msg sends the given text to the current target, be it either a channel or a specific user.



120
121
122
# File 'lib/marvin/base.rb', line 120

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

#pm(message, target) ⇒ Object

A conditional version of message that will only send the message if the target / from is a user. To do this, it uses from_channel?



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

def pm(message, target)
  say(message, target) unless from_channel?(target)
end

#registered=(value) ⇒ Object

A Perennial automagical helper for dispatch



170
171
172
# File 'lib/marvin/base.rb', line 170

def registered=(value)
  self.class.registered = value
end

#reply(message) ⇒ Object

Replies to a message. if it was received in a channel, it will use the standard irc "Name: text" convention for replying whilst if it was in a direct message it sends it as is.



139
140
141
142
143
144
145
# File 'lib/marvin/base.rb', line 139

def reply(message)
  if from_channel?
    say("#{from}: #{message}")
  else
    say(message, from)
  end
end