aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--PyRC.py465
1 files changed, 233 insertions, 232 deletions
diff --git a/PyRC.py b/PyRC.py
index 3957b24..4571e25 100644
--- a/PyRC.py
+++ b/PyRC.py
@@ -1,237 +1,238 @@
-"""A module to connect to and interact with an Internet Relay Chat server.
+"""
+A module to connect to and interact with an Internet Relay Chat server.
"""
+import select
import socket
-import sys
import string
-import select
+import sys
-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
+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