Class: EventMachine::IRC::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/em-irc/client.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) {|client| ... } ⇒ Client

Build a new unconnected IRC client

Parameters:

  • options (Hash) (defaults to: {})

Options Hash (options):

  • :host (String)
  • :port (String)
  • :ssl (Boolean)
  • :nick (String)
  • :realname (String)

Yields:

  • (client)

    new instance for decoration



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/em-irc/client.rb', line 37

def initialize(options = {}, &blk)
  options.symbolize_keys!
  options = {
    host:     '127.0.0.1',
    port:     '6667',
    ssl:      false,
    realname: 'Anonymous Annie',
    nick:     "guest-#{Time.now.to_i % 1000}"
  }.merge!(options)

  @host      = options[:host]
  @port      = options[:port]
  @ssl       = options[:ssl]
  @realname  = options[:realname]
  @nick      = options[:nick]
  @channels  = Set.new
  @callbacks = Hash.new
  @connected = false
  yield self if block_given?
end

Instance Attribute Details

#hostObject

IRC server to connect to. Defaults to 127.0.0.1:6667



9
10
11
# File 'lib/em-irc/client.rb', line 9

def host
  @host
end

#loggerObject

Custom logger



16
17
18
# File 'lib/em-irc/client.rb', line 16

def logger
  @logger
end

#nickObject

Returns the value of attribute nick.



11
12
13
# File 'lib/em-irc/client.rb', line 11

def nick
  @nick
end

#portObject

IRC server to connect to. Defaults to 127.0.0.1:6667



9
10
11
# File 'lib/em-irc/client.rb', line 9

def port
  @port
end

#realnameObject

Returns the value of attribute realname.



12
13
14
# File 'lib/em-irc/client.rb', line 12

def realname
  @realname
end

#sslObject

Returns the value of attribute ssl.



13
14
15
# File 'lib/em-irc/client.rb', line 13

def ssl
  @ssl
end

Instance Method Details

#connectEventMachine::Connection

Creates a Eventmachine TCP connection with :host and :port. It should be called after callbacks are registered.

Returns:

  • (EventMachine::Connection)

See Also:



62
63
64
# File 'lib/em-irc/client.rb', line 62

def connect
  self.conn ||= EventMachine::connect(@host, @port, Dispatcher, parent: self)
end

#connected?Boolean

Returns:

  • (Boolean)


67
68
69
# File 'lib/em-irc/client.rb', line 67

def connected?
  @connected
end

#handle_parsed_message(m) ⇒ Object



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# File 'lib/em-irc/client.rb', line 158

def handle_parsed_message(m)
  case m[:command]
  when '001' # welcome message
  when 'PING'
    pong(m[:params].first)
    trigger(:ping, *m[:params])
  when 'PRIVMSG'
    trigger(:message, m[:prefix], m[:params].first, m[:params].slice(1..-1).join(' '))
  when 'QUIT'
  when 'JOIN'
    trigger(:join, m[:prefix], m[:params].first)
  else
    # noop
    # {:prefix=>"irc.the.net", :command=>"433", :params=>["*", "one", "Nickname", "already", "in", "use", "irc.the.net", "451", "*", "Connection", "not", "registered"]}
    # {:prefix=>"irc.the.net", :command=>"432", :params=>["*", "one_1328243723", "Erroneous", "nickname"]}
  end
  trigger(:raw, m)
end

#join(channel_name, channel_key = nil) ⇒ Object



124
125
126
# File 'lib/em-irc/client.rb', line 124

def join(channel_name, channel_key = nil)
  send_data("JOIN #{channel_name} #{channel_key}".strip)
end

#log(*args) ⇒ Object



198
199
200
# File 'lib/em-irc/client.rb', line 198

def log(*args)
  @logger.log(*args) if @logger
end

#on(name, &blk) ⇒ Object

Register a callback with :name as one of the following, and a block with the same number of params.

Examples:

on(:join) {|channel| puts channel}

:connect - called after connection to server established

:join
  @param who [String]
  @param channel [String]
  @param names [Array]

:message, :privmsg - called on channel message or nick message
  @param source [String]
  @param target [String]
  @param message [String]

:raw - called for all messages from server
  @param raw_hash [Hash] same format as return of #parse_message


93
94
95
96
97
# File 'lib/em-irc/client.rb', line 93

def on(name, &blk)
  # TODO: I thought Hash.new([]) would work, but it gets empted out
  # TODO: normalize aliases :privmsg, :message, etc
  (@callbacks[name.to_sym] ||= []) << blk
end

#pong(servername) ⇒ Object



128
129
130
# File 'lib/em-irc/client.rb', line 128

def pong(servername)
  send_data("PONG :#{servername}")
end

#privmsg(target, message) ⇒ Object Also known as: message

Parameters:

  • target (String)

    nick or channel name

  • message (String)


134
135
136
# File 'lib/em-irc/client.rb', line 134

def privmsg(target, message)
  send_data("PRIVMSG #{target} :#{message}")
end

#quit(message = 'leaving') ⇒ Object



139
140
141
# File 'lib/em-irc/client.rb', line 139

def quit(message = 'leaving')
  send_data("QUIT :#{message}")
end

#receive_data(data) ⇒ Object

EventMachine Callbacks



178
179
180
181
182
183
# File 'lib/em-irc/client.rb', line 178

def receive_data(data)
  data.split("\r\n").each do |message|
    parsed = parse_message(message)
    handle_parsed_message(parsed)
  end
end

#renick(nick) ⇒ Object

Client commands See [RFC 2812](tools.ietf.org/html/rfc2812)



116
117
118
# File 'lib/em-irc/client.rb', line 116

def renick(nick)
  send_data("NICK #{nick}")
end

#run!Object



202
203
204
205
206
207
208
209
210
211
212
# File 'lib/em-irc/client.rb', line 202

def run!
  EM.epoll
  EventMachine.run do
    trap("TERM") { EM::stop }
    trap("INT")  { EM::stop }
    connect
    log Logger::INFO, "Starting IRC client..."
  end
  log Logger::INFO, "Stopping IRC client"
  @logger.close if @logger
end

#send_data(message) ⇒ Object

Sends raw message to IRC server. Assumes message is correctly formatted TODO: what if connect fails? or disconnects?



107
108
109
110
111
112
# File 'lib/em-irc/client.rb', line 107

def send_data(message)
  return false unless connected?
  message = message + "\r\n"
  log Logger::DEBUG, message
  self.conn.send_data(message)
end

#trigger(name, *args) ⇒ Object

Trigger a named callback



100
101
102
103
# File 'lib/em-irc/client.rb', line 100

def trigger(name, *args)
  # TODO: should this be instance_eval(&blk)? prevents it from non-dsl style
  (@callbacks[name.to_sym] || []).each {|blk| blk.call(*args)}
end

#user(username, mode, realname) ⇒ Object



120
121
122
# File 'lib/em-irc/client.rb', line 120

def user(username, mode, realname)
  send_data("USER #{username} #{mode} * :#{realname}")
end