import sys, os from twisted.internet import reactor, defer from twisted.internet.protocol import ClientCreator from flaxserv import protocol, util, config, store sys.path.append(os.path.abspath('..')) # to appease pickle class ControlConnection(protocol.IRCConnection): def __init__(self, hostname): self.loginDeferred = None self.cmdSerial = 0 self.cmdDeferreds = {} protocol.IRCConnection.__init__(self, hostname) def login(self, nickPrefix): self.nickPrefix = nickPrefix self.nickSerial = -1 self.loginDeferred = defer.Deferred() self.nick = self._getNick() self.send('NICK', self.nick) self.send('USER', self.nick, '0', self.hostname, data='FlaxServ control connection') return self.loginDeferred def irc_001(self, args, prefix, data): "RPL_WELCOME - first reply sent after successful auth" self.loginDeferred.callback(self) def irc_433(self, args, prefix, data): "Nickname already in use" self.nick = self._getNick() self.send('NICK', self.nick) def irc_NOTICE(self, args, frm, data): frm = frm.split('!', 1)[0] # was something like NickServ!services@services.pentabarf.net if frm.lower() == config.NICKSERVNICK.lower(): (cmd, data) = data.split(None, 1) method = getattr(self, 'ns_%s' % cmd.upper(), None) if method: method(frm, data) def ns_RESPONSE(self, frm, data): (sig, data) = data.split(None, 1) if util.validsig(sig, data, config.SALT): response = util.unserialize(data) cmdid = response.pop(0) result = response.pop(0) print "got cmdid", cmdid if cmdid in self.cmdDeferreds: print "doing callback" print "result =", result self.cmdDeferreds[cmdid].callback(result) def _getNick(self): self.nickSerial += 1 return "%s%d" % (self.nickPrefix, self.nickSerial) def connectionMade(self): if not self.hostname: self.hostname = self.transport.getHost().host protocol.IRCConnection.connectionMade(self) def privmsg(self, to, text): self.send('PRIVMSG', to, prefix=self.nick, data=text) def cmd(self, *args): d = defer.Deferred() cmdid = str(self.cmdSerial) self.cmdSerial += 1 self.cmdDeferreds[cmdid] = d text = util.serialize((cmdid,) + args) sig = util.sign(text, config.SALT) self.privmsg(config.NICKSERVNICK, ' '.join(['CONTROL', sig, text])) return d def connect(server, nick, hostname=None): d = defer.Deferred() ClientCreator(reactor, ControlConnection, hostname ).connectTCP(*server ).addErrback(d.errback ).addCallback(lambda conn: conn.login(nick).chainDeferred(d)) return d if __name__ == '__main__': from twisted.internet import reactor from twisted.python import log import sys from flaxserv import config def goGoGo(conn): print "connected!" print conn.nick for i in range(10): conn.cmd('fnord:\\:').addCallback(log.msg) log.startLogging(sys.stdout) connect((config.SERVER, int(config.PORT)), 'flaxcontrol').addCallback(goGoGo) reactor.run()