Class: Marvin::Base

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

Direct Known Subclasses

CommandHandler, Distributed::Handler

Constant Summary collapse

@@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.



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

def client
  @client
end

#fromObject

Returns the value of attribute from.



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

def from
  @from
end

#optionsObject

Returns the value of attribute options.



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

def options
  @options
end

#targetObject

Returns the value of attribute target.



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

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)



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

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)



43
44
45
46
# File 'lib/marvin/base.rb', line 43

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.



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

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.



57
58
59
60
61
# File 'lib/marvin/base.rb', line 57

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



22
23
24
# File 'lib/marvin/base.rb', line 22

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

.registered?Boolean

Returns:

  • (Boolean)


18
19
20
# File 'lib/marvin/base.rb', line 18

def registered?
  @registered ||= false
end

.reloaded!Object



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

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



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

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)



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

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



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

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

#addressed?Boolean

Returns:

  • (Boolean)


163
164
165
# File 'lib/marvin/base.rb', line 163

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

#ctcp(message) ⇒ Object



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

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)

Returns:

  • (Boolean)


159
160
161
# File 'lib/marvin/base.rb', line 159

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.

Returns:

  • (Boolean)


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

def from_user?
  !from_channel?
end

#handle(message, options) ⇒ Object



88
89
90
# File 'lib/marvin/base.rb', line 88

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.



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

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.



118
119
120
# File 'lib/marvin/base.rb', line 118

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?



130
131
132
# File 'lib/marvin/base.rb', line 130

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

#registered=(value) ⇒ Object

A Perennial automagical helper for dispatch



168
169
170
# File 'lib/marvin/base.rb', line 168

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.



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

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