Module: BeerBot::Codecs::IRC

Defined in:
lib/beerbot/02.codecs/irc.rb

Overview

IRC Protcol module.

Main method is parse, whose job is to receive incoming irc strings and convert to a generalised format that higher layers like the dispatcher can use.

Defined Under Namespace

Classes: IRCMessage

Constant Summary collapse

ACTION_REGEX =
/\u0001ACTION\s+(.+)\u0001/

Class Method Summary collapse

Class Method Details

.action(to, str) ⇒ Object

Send a /me-style action to channel or nick.



275
276
277
# File 'lib/beerbot/02.codecs/irc.rb', line 275

def self.action to,str
  "PRIVMSG #{to} :\u0001#{'ACTION'} #{str}\u0001"
end

.decode(str) ⇒ Object

Parse raw irc string and then yield or return a generic representation of the event.

Returns [event,*args]

Parse’s job is to take the constituents parts of an irc message, identify the type of event and return a generic representation of it.

So for instance, an irc privmsg (message) is represented as

[:msg,from,to,msg]

Note that connection readiness and PONG protocol are handled by the irc connection, not here.



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
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
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/beerbot/02.codecs/irc.rb', line 35

def self.decode str

  m = IRCMessage.new(str)
  result = []

  case m[:command]

  when 'NICK'  # change of nick
    case s=m.check(:prefix,:nick,:trailing)
    when Symbol
      puts "* NICK expected #{s}"
      return nil
    end
    old = m[:prefix][:nick]
    nick = m[:trailing]
    result = [:nick,old,nick]


  when 'QUIT' # someone leaves irc
    case s=m.check(:prefix,:nick,:trailing)
    when Symbol
      puts "* QUIT expected #{s}"
      return nil
    end
    nick = m[:prefix][:nick]
    msg = m[:trailing]
    result = [:quit,nick,msg]

  when 'PART' # someone leaves channel
    case s=m.check(:prefix,:nick,:params)
    when Symbol
      puts "* PART expected #{s}"
      return nil
    end
    if channel=m[:params][0] then
    elsif channel=m[:trailing].strip.split(/\s+/).first then
    else
      channel=nil
      puts "* PART can't determine what is being parted from: '#{str}'"
      return nil
    end
    nick = m[:prefix][:nick]
    result = [:part,nick,channel]

  when 'INVITE' # someone invites us, oo
    ournick = m[:params][0]
    chan = m[:trailing].strip.split(/\s+/).first
    result = [:invite,chan]

  when 'JOIN' # someone joins channel
    case s=m.check(:prefix,:nick,:trailing)
    when Symbol
      puts "* JOIN expected #{s}"
      return nil
    end
    channel = m[:trailing]
    nick = m[:prefix][:nick]
    result = [:join,nick,channel]

  when '353'  # channel user list when we join the channel
    case s=m.check(:params,:trailing)
    when Symbol
      puts "* 353 expected #{s}"
      return nil
    end
    channel = m[:params][2]
    users = m[:trailing].split(/\s+/)
    result = [:chanlist,channel,users]
    #puts "[decode/353] #{result}"

  when '366'  # end of 353
    result = [:chanlistend]

  when 'PRIVMSG'
    case s=m.check(:prefix,:nick,:params,:trailing)
    when Symbol
      #puts "* PRIVMSG expected #{s}"
      return nil
    end

    msg  = m[:trailing].strip
    from = m[:prefix][:nick].strip
    to   = m[:params][0].strip unless m[:params].empty?
    if action = self.match_action(msg) then
      result = [:action,from,to,action]
    else
      result = [:msg,from,to,msg]
    end

  else # command we don't handle
    result = [:default,m]
  end

  result
end

.encode(botmsg) ⇒ Object

Return irc-conformat string from a botmsg.

Generates nil if it can’t handle ‘botmsg’.



238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
# File 'lib/beerbot/02.codecs/irc.rb', line 238

def self.encode botmsg
  case botmsg
  when Hash
    to = botmsg[:to]
    return nil unless to
    if botmsg[:action] then
      self.action(to,botmsg[:action])
    elsif botmsg[:msg] then
      self.msg(to,botmsg[:msg])
    else
      nil
    end
  when Array
    botmsg.map{|reply|
      self.encode reply
    }
  when Proc
    #p botmsg.call
    self.encode(botmsg.call)
  else
    nil
  end

end

.join(chan) ⇒ Object

Join a channel



297
298
299
# File 'lib/beerbot/02.codecs/irc.rb', line 297

def self.join chan
  "JOIN #{chan}"
end

.leave(chan) ⇒ Object

Leave channel.



303
304
305
# File 'lib/beerbot/02.codecs/irc.rb', line 303

def self.leave chan
  "PART #{chan}"
end

.match_action(str) ⇒ Object

Returns string matching the action (the bit after ACTION) or nil.

eg

danb does something => "does something"


286
287
288
289
290
291
292
293
# File 'lib/beerbot/02.codecs/irc.rb', line 286

def self.match_action str
  m = ACTION_REGEX.match(str)
  if m then
    m[1].strip
  else
    nil
  end
end

.msg(to, str) ⇒ Object Also known as: privmsg

Send PRIVMSG to channel or nick.



266
267
268
# File 'lib/beerbot/02.codecs/irc.rb', line 266

def self.msg to,str
  "PRIVMSG #{to} :#{str}"
end