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

- (Object) client

Returns the value of attribute client



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

def client
  @client
end

- (Object) from

Returns the value of attribute from



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

def from
  @from
end

- (Object) options

Returns the value of attribute options



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

def options
  @options
end

- (Object) target

Returns the value of attribute target



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

def target
  @target
end

Class Method Details

+ (Object) event_handlers_for(message_name)

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

+ (Object) on_event(name, method_name = nil, &blk)

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

+ (Object) on_numeric(value, method_name = nil, &blk)

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

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

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

+ (Object) registered=(value)



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

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

+ (Boolean) registered?

Returns:

  • (Boolean)


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

def registered?
  @registered ||= false
end

+ (Object) reloaded!



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

+ (Object) reloading!



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

- (Object) _handle(message, options)

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

- (Object) action(message, target = self.target)



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

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

- (Boolean) addressed?

Returns:

  • (Boolean)


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

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

- (Object) ctcp(message)



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

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

- (Boolean) from_channel?(target = self.target)

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

Returns:

  • (Boolean)


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

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

- (Boolean) from_user?

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

Returns:

  • (Boolean)


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

def from_user?
  !from_channel?
end

- (Object) handle(message, options)



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

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

- (Object) handle_incoming_numeric(opts)

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

- (Object) msg(message, target = self.target) 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

- (Object) pm(message, target)

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

- (Object) registered=(value)

A Perennial automagical helper for dispatch



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

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

- (Object) reply(message)

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