Module: Net::IRCOutputAPI

Included in:
YAIL
Defined in:
lib/net/yail/output_api.rb

Overview

This module is responsible for the raw socket output, buffering of all “message” types of events, and exposing the magic to create a new output command + handler. All output methods are documented in the main Net::YAIL documentation.

Instance Method Summary collapse

Instance Method Details

#act(target, message) ⇒ Object

Buffers an :outgoing_act event. Target is user or channel, message is message.



38
39
40
# File 'lib/net/yail/output_api.rb', line 38

def act(target, message)
  buffer_output Net::YAIL::OutgoingEvent.new(:type => :act, :target => target, :message => message)
end

#buffer_output(event) ⇒ Object

Buffers the given event to be sent out when we are able to send something out to the given target. If buffering isn’t turned on, the event will be processed in the next loop of outgoing messages.



18
19
20
21
22
23
# File 'lib/net/yail/output_api.rb', line 18

def buffer_output(event)
  @privmsg_buffer_mutex.synchronize do
    @privmsg_buffer[event.target] ||= Array.new
    @privmsg_buffer[event.target].push event
  end
end

#create_command(command, output_base, *opts) ⇒ Object

Creates an output command and its handler. output_base is a template of the command without any conditional arguments (for simple commands this is the full template). args is a list of argument symbols to determine how the event is built and handled. If an argument symbol is followed by a string, that string is conditionally appended to the output in the handler if the event has data for that argument.

I hate the hackiness here, but it’s so much easier to build the commands and handlers with an ugly one-liner than manually, and things like define_method seem to fall short with how much crap this needs to do.



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/net/yail/output_api.rb', line 60

def create_command(command, output_base, *opts)
  event_opts = lambda {|text| text.gsub(/:(\w+)/, '#{event.\1}') }

  output_base = event_opts.call(output_base)

  # Create a list of actual arg symbols and templates for optional args
  args = []
  optional_arg_templates = {}
  last_symbol = nil
  for opt in opts
    case opt
    when Symbol
      args.push opt
      last_symbol = opt
    when String
      raise ArgumentError.new("create_command optional argument must have an argument symbol preceding them") unless last_symbol
      optional_arg_templates[last_symbol] = event_opts.call(opt)
      last_symbol = nil
    end
  end

  # Format strings for command args and event creation
  event_string = args.collect {|arg| ":#{arg} => #{arg}"}.join(",")
  event_string = ", #{event_string}" unless event_string.empty?
  args_string = args.collect {|arg| "#{arg} = ''"}.join(",")

  # Create the command function
  command_code = %Q|
    def #{command}(#{args_string})
      dispatch Net::YAIL::OutgoingEvent.new(:type => #{command.inspect}#{event_string})
    end
  |
  self.class.class_eval command_code

  # Create the handler piece by piece - wow how ugly this is!
  command_handler = :"magic_out_#{command}"
  handler_code = %Q|
    def #{command_handler}(event)
      output_string = "#{output_base}"
  |
  for arg in args
    if optional_arg_templates[arg]
      handler_code += %Q|
        output_string += "#{optional_arg_templates[arg]}" unless event.#{arg}.to_s.empty?
      |
    end
  end
  handler_code += %Q|
      raw output_string
    end
  |

  self.class.class_eval handler_code

  # At least setting the callback isn't a giant pile of dumb
  set_callback :"outgoing_#{command}", self.method(command_handler)
end

#ctcp(target, message) ⇒ Object

Buffers an :outgoing_ctcp event. Target is user or channel, message is message.



33
34
35
# File 'lib/net/yail/output_api.rb', line 33

def ctcp(target, message)
  buffer_output Net::YAIL::OutgoingEvent.new(:type => :ctcp, :target => target, :message => message)
end

#msg(target, message) ⇒ Object

Buffers an :outgoing_msg event. Could be used to send any privmsg, but you’re betting off using act and ctcp shortcut methods for those types. Target is a channel or username, message is the message.



28
29
30
# File 'lib/net/yail/output_api.rb', line 28

def msg(target, message)
  buffer_output Net::YAIL::OutgoingEvent.new(:type => :msg, :target => target, :message => message)
end

#raw(line) ⇒ Object

Spits a raw string out to the server - in case a subclass wants to do something special on all output, please make all output go through this method. Don’t use puts manually. I will kill violaters. Legally speaking, that is.



11
12
13
# File 'lib/net/yail/output_api.rb', line 11

def raw(line)
  @socket.puts "#{line}\r\n"
end

#whois(nick, server = nil) ⇒ Object

WHOIS is tricky - it can optionally take a :target parameter, which is the first parameter if it’s present, rather than added to the parameter list. BAD SPECIFICATIONS! NO BISCUIT! (If it were more standard, we could just use create_command)

Note that “nick” can actually be a comma-separated list of masks for whois querying.



47
48
49
# File 'lib/net/yail/output_api.rb', line 47

def whois(nick, server = nil)
  dispatch Net::YAIL::OutgoingEvent.new(:type => :whois, :nick => nick, :server => server)
end