diff options
| author | 2013-04-17 14:09:54 -0400 | |
|---|---|---|
| committer | 2013-04-17 14:09:54 -0400 | |
| commit | 381bbd7e521f56fdb61e86ce9fc039e6f3b7cf91 (patch) | |
| tree | 77599b9eefc686e6ea94cb83c61f065d96e00cc6 | |
| download | pyrc-381bbd7e521f56fdb61e86ce9fc039e6f3b7cf91.tar.gz pyrc-381bbd7e521f56fdb61e86ce9fc039e6f3b7cf91.tar.bz2 pyrc-381bbd7e521f56fdb61e86ce9fc039e6f3b7cf91.zip | |
Initial commit
| -rw-r--r-- | PyRC.py | 237 |
1 files changed, 237 insertions, 0 deletions
@@ -0,0 +1,237 @@ +"""A module to connect to and interact with an Internet Relay Chat server. +""" + +import socket +import sys +import string +import select + +class client: + def __init__(self, (host, port, hostpass)): + try: + self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.s.setblocking(0) + except socket.error, msg: + self.s = None + if self.s is None: + print 'Could not open socket.' + sys.exit(1) + + self.host = host + self.port = port + self.hostpass = hostpass + self.send_buf = '' + self.recv_buf = '' + + def connect(self, (nick, ident, realname)): + """connect((nick, ident, realname)) + + Connects to the specified host.""" + try: + self.s.connect((self.host, self.port)) + except socket.error, msg: + if (msg[0] == 115): + pass + else: + self.s.close() + self.s = None + if self.s is None: + print "Could not connect to %s %s" % (self.host, self.port) + sys.exit(1) + + connected = False + while not connected: + try: + if self.hostpass: + self.s.send('PASS %s\r\n' % self.hostpass) + self.s.send('NICK %s\r\n' % nick) + # TODO: try alternate nicknames if the first is taken, or just fail. + self.s.send('USER %s %s %s :%s\r\n' % (nick, socket.gethostname(), self.host, realname)) + connected = True + except socket.error, msg: + if msg[0] == 11 or msg[0] == 115: + pass + else: + self.s.close() + self.s = None + if self.s is None: + print "Could not connect to %s %s" % (self.host, self.port) + sys.exit(1) + + def quit(self, reason = ''): + """quit([reason]) -> string + + Disconnects from host and returns final server messages.""" + + connected = True + while connected: + try: + if reason: + self.s.send('QUIT :%s\r\n' % reason) + connected = False + else: + self.s.send('QUIT :PyRC. http://www.pyrc.org\r\n') + connected = False + except socket.error, msg: + if msg[0] == 11: + pass + else: + self.s.close() + self.s = None + if self.s is None: + print "Could not send to %s %s" % (self.host, self.port) + sys.exit(1) + + def join(self, channel, key = ''): + """join(channel[, key]) + + Joins specified channel, optionally using a channel key.""" + try: + self.s.send('JOIN %s %s\r\n' % (channel, key)) + except socket.error, msg: + if msg[0] == 11: + pass + else: + self.s.close() + self.s = None + if self.s is None: + print "Could not send to %s %s" % (self.host, self.port) + sys.exit(1) + + def part(self, channel): + """part(channel) + + Leaves specified channel.""" + try: + self.s.send('PART %s\r\n' % channel) + except socket.error, msg: + if msg[0] == 11: + pass + else: + self.s.close() + self.s = None + if self.s is None: + print "Could not send to %s %s" % (self.host, self.port) + sys.exit(1) + + def message(self, dest, message): + """message(dest, message) + + Sends message to specified destination. May be channel or user.""" + try: + self.s.send('PRIVMSG %s :%s\r\n' % (dest, message)) + except socket.error, msg: + if msg[0] == 11: + pass + else: + self.s.close() + self.s = None + if self.s is None: + print "Could not send to %s %s" % (self.host, self.port) + sys.exit(1) + + def notice(self, dest, message): + """notice(dest, message) + + Sends notice to specified destination. May be channel or user.""" + try: + self.s.send('NOTICE %s :%s\r\n' % (dest, message)) + except socket.error, msg: + if msg[0] == 11: + pass + else: + self.s.close() + self.s = None + if self.s is None: + print "Could not send to %s %s" % (self.host, self.port) + sys.exit(1) + + def invite(self, dest, channel): + """invite(dest, channel) + + Invites user to the specified channel.""" + try: + self.s.send('INVITE %s %s\r\n' % (dest, channel)) + except socket.error, msg: + if msg[0] == 11: + pass + else: + self.s.close() + self.s = None + if self.s is None: + print "Could not send to %s %s" % (self.host, self.port) + sys.exit(1) + + def nick(self, nickname): + """nick(nickname) + + Changes nickname to the specified nickname.""" + try: + self.s.send('NICK %s\r\n' % nickname) + except socket.error, msg: + if msg[0] == 11: + pass + else: + self.s.close() + self.s = None + if self.s is None: + print "Could not send to %s %s" % (self.host, self.port) + sys.exit(1) + + def pong(self, dest): + """pong(dest, message) + + Sends a pong to specified destination.""" + try: + self.s.send('PONG %s\r\n' % dest) + except socket.error, msg: + if msg[0] == 11: + pass + else: + self.s.close() + self.s = None + if self.s is None: + print "Could not send to %s %s" % (self.host, self.port) + sys.exit(1) + + def main_loop(self): + """main_loop() + + Returns an array of dictionary objects, with keys 'sender', + 'type', 'destination', and 'message'.""" + tempbuff = '' + try: + while 1: + tempbuff += self.s.recv(512) + except socket.error, msg: + if msg[0] == 11: + self.recv_buf += tempbuff + else: + self.s.close() + self.s = None + if self.s is None: + print "Could not recieve from %s %s" % (self.host, self.port) + sys.exit(1) + + while self.recv_buf: + msgs = [] + temp = self.recv_buf.split('\n') + self.recv_buf = temp.pop() + for line in temp: + line = line.strip() + line = line.split(' ') + if line[0] == 'PING': + self.pong(line[1]) + elif line[0] == 'ERROR': + msgs.append({'sender': None, 'type': line[0], 'destination': None, 'message': string.join(line[1:]).lstrip(':')}) + self.s.close() + else: + if (line[0][0] == ':'): + # if there is a sender (usually) + # [ sender, action, destination, message ] + msgs.append({'sender': line[0].lstrip(':'), 'type': line[1], 'destination':line[2], 'message': string.join(line[3:]).lstrip(':')}) + else: + #if no sender + # [ '', action, destination, message ] + msgs.append({'sender': None, 'type': line[0], 'destination': line[1], 'message': string.join(line[2:]).lstrip(':')}) + return msgs |