local cqueues = require'cqueues' local socket = require'cqueues.socket' local pprint = require'pprint' local rirc = require'rirc' local Queue = require'queue' local Irc = {} function Irc._send(self, args) args.source = args.source or self.nodename local sent = rirc.send(self.sock, args) print('>', sent) end function Irc.makepylon(pylonname, conf, cq, network) local self = { pylonname=pylonname, cq = cq, network = network, inbox = Queue.make(), } local function conf_var(name) assert(conf[name] ~= nil, 'missing conf field '..name) self[name] = conf[name] end conf_var 'host' conf_var 'port' conf_var 'password' conf_var 'nodename' setmetatable(self, {__index=Irc}) return self end function Irc._connect(self) self.sock = assert(socket.connect(self.host, self.port)) self:_send{'PASS', self.password, '0210-IRC', 'wilson|'} self:_send{'SERVER', self.nodename, '1', 'i am wilson'} end function Irc.run(self) self:_connect() self.cq:wrap(self.recving, self) self.cq:wrap(self.sending, self) end function Irc.recving(self) for line in self.sock:lines "*l" do print('<', line) local msg = rirc.parse(line) if msg.op == 'PING' then self:_send{'PONG', msg.args[1]} elseif msg.op == 'PRIVMSG' then local channel = msg.args[1] local body = msg.args[2] local source = msg.source self.network:post(self.pylonname, channel, { body = body, source = source..'[i]' }) end end end function Irc.sending(self) local nicks_channels = {} local function ensure_joined(nick, channel) if not nicks_channels[nick] then self:_send{'NICK', nick, 1, 'username', 'host', 1, '+', 'realname'} nicks_channels[nick] = {} end if not nicks_channels[nick][channel] then self:_send{source=nick, 'JOIN', channel} nicks_channels[nick][channel] = true end end local function say(nick, channel, body) ensure_joined(nick, channel) self:_send{source=nick, 'PRIVMSG', channel, body} end say('WILSON', '#test', 'i am wilson') for ch, msg in self.inbox:iter() do say(msg.source, ch, msg.body) end end return Irc -- local cq = cqueues.new() -- local conf = { -- host = 'localhost', -- port = '6667', -- password = 'mypassword', -- nodename = 'wilson.ubq323', -- } -- local dummy_network = { -- post = function(self, pylonname, channel, message) -- pprint(pylonname, channel, message) -- end -- } -- local pylon = Irc.makepylon('test', conf, cq, dummy_network) -- pylon:run() -- cq:wrap(function() -- local i = 0 -- while true do -- cqueues.sleep(1) -- pylon.inbox:enqueue{ -- source = 'helen', -- channel = '#test', -- body = 'i am helen '..i, -- } -- i = i + 1 -- end -- end) -- pprint('cheese', cq:loop())