Advertisement
MegaLoler

Minimal IRC Client Library

Apr 29th, 2012
136
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.34 KB | None | 0 0
  1. import socket
  2. import thread
  3.  
  4. # A minimalistic library for connecting to IRC
  5.  
  6. class IRCCommand:
  7.     def __init__(self, msg=""):
  8.         if msg == "": return
  9.         msg = msg.strip()
  10.         self.msg = msg
  11.  
  12.         while "  " in msg:
  13.             msg = msg.replace("  ", " ")
  14.  
  15.         if msg[0] == ":":
  16.             prefix = msg[1:msg.find(" ")]
  17.         else:
  18.             prefix = ""
  19.             nick = ""
  20.             user = ""
  21.             host = ""
  22.             servername = ""
  23.  
  24.         if prefix != "":
  25.             if prefix.find("!") == -1:
  26.                 nick = ""
  27.                 user = ""
  28.                 host = ""
  29.                 servername = prefix
  30.             else:
  31.                 servername = ""
  32.                 nick = prefix[0:prefix.find("!")]
  33.                 user = prefix[prefix.find("!")+1:prefix.find("@")]
  34.                 host = prefix[prefix.find("@")+1:]
  35.  
  36.         if prefix != "":
  37.             msg = msg[msg.find(" ")+1:]
  38.  
  39.         if msg.find(" ") == -1:
  40.             command = msg.upper()
  41.             params = ""
  42.             trailing = ""
  43.         else:
  44.             command = msg[0:msg.find(" ")].upper()
  45.             params = msg[msg.find(" ")+1:]
  46.  
  47.         if params != "":
  48.             if params.find(":") == -1:
  49.                 trailing = ""
  50.             else:
  51.                 trailing = params[params.find(":")+1:]
  52.                 params = params[0:params.find(":")-1]
  53.  
  54.         paramList = params.split(" ")
  55.  
  56.         self.prefix = prefix
  57.         self.servername = servername
  58.         self.nick = nick
  59.         self.user = user
  60.         self.host = host
  61.         self.command = command
  62.         self.params = params
  63.         self.trailing = trailing
  64.         self.paramList = paramList
  65.    
  66.     def __str__(self):
  67.         return self.msg
  68.    
  69.     def formatted(self):
  70.       if self.command in ["PRIVMSG", "NOTICE"]:
  71.         return self.paramList[0] + ": " + self.nick + ": " + self.trailing
  72.       return 0
  73.  
  74. class IRCServer:
  75.     def __init__(self, host, port=6667):
  76.         self.host = host
  77.         self.port = port
  78.         self.sock = socket.socket()
  79.  
  80.         self.favoriteChannels = []
  81.  
  82.         self.connected = False
  83.         self.identified = False
  84.         self.joined = False
  85.         self._buffer = ""
  86.         self._messages = []
  87.  
  88.         self.verbose = False
  89.         self.pretty = False
  90.  
  91.         self.logMode = False
  92.         self.rawLogFile = "logRAW.txt"
  93.         self.formattedLogFile = "log.txt"
  94.        
  95.         self.nick = ""
  96.         self.password = ""
  97.        
  98.         self.echo = False
  99.  
  100.     def addFavoriteChannel(self, channel):
  101.         self.favoriteChannels.append(channel)
  102.  
  103.     def removeFavoriteChannel(self, channel):
  104.         self.favoriteChannels.remove(channel)
  105.  
  106.     def connect(self, nick, password="", user="", real=""):
  107.         self.nick = nick
  108.         self.password = password
  109.        
  110.         if user == "": user = nick.lower()
  111.         if real == "": real = nick
  112.  
  113.         self.sock.connect((self.host, self.port))
  114.         self.connected = True
  115.  
  116.         thread.start_newthread(self._listen, ())
  117.  
  118.         self._sendCommand("nick", [nick])
  119.         self._sendCommand("user", [user, "8", "*"], real)
  120.  
  121.     def disconnect(self, msg=""):
  122.         self._sendCommand("quit", [msg])
  123.  
  124.         self.sock.close()
  125.         self.connected = False
  126.         self.identified = False
  127.  
  128.     def poll(self):
  129.         messages = self._messages
  130.         self._messages = []
  131.         return messages
  132.  
  133.     def kick(self, user, channel, reason=""):
  134.         self._sendCommand("kick", [channel, user], reason)
  135.  
  136.     def ban(self, user, channel):
  137.         self._sendCommand("mode", [channel, "+b", user+"!*@*"])
  138.  
  139.     def op(self, user, channel):
  140.         self._sendCommand("mode", [channel, "+o", user])
  141.        
  142.     def action(self, msg, channel):
  143.         self.say(chr(1)+"ACTION " + msg + chr(1), channel)
  144.  
  145.     def say(self, msg, channel):
  146.         if self.echo:
  147.             cmd = IRCCommand()
  148.             cmd.nick = self.nick
  149.             cmd.command = "PRIVMSG"
  150.             cmd.trailing = msg
  151.             cmd.paramList = [channel]
  152.             self._messages.append(cmd)
  153.         for msg in msg.split("\n"):
  154.             self._sendCommand("privmsg", [channel], msg)
  155.             self.logPretty2(channel + ": " + self.nick + ": " + msg)
  156.  
  157.     def notice(self, msg, channel):
  158.         self._sendCommand("notice", [channel], msg)
  159.         self.logPretty2(channel + ": " + self.nick + ": " + msg)
  160.  
  161.     def join(self, channel):
  162.         self._sendCommand("join", [channel])
  163.  
  164.     def part(self, channel):
  165.         self._sendCommand("part", [channel])
  166.  
  167.     def joinFavorites(self):
  168.         for fav in self.favoriteChannels:
  169.             self.join(fav)
  170.            
  171.     def verboseOut(self, msg):
  172.       if self.verbose: print( msg)
  173.       if self.logMode:
  174.         f = open(self.rawLogFile, 'a')
  175.         f.write(msg + "\n")
  176.         f.close()
  177.    
  178.     def logPretty(self, cmd):
  179.       self.logPretty2(cmd.formatted())
  180.    
  181.     def logPretty2(self, msg):
  182.       if msg == 0: return
  183.       if self.pretty: print(msg)
  184.       if self.logMode:
  185.         f = open(self.formattedLogFile, 'a')
  186.         f.write(msg + "\n")
  187.         f.close()
  188.  
  189.     def _listen(self):
  190.         while self.connected:
  191.             self._buffer += self.sock.recv(1024).decode()
  192.             if(self._buffer.find("\r\n")):
  193.                 for msg in self._buffer.split("\r\n")[0:-1]:
  194.                     self.verboseOut("SERVER: " + msg)
  195.                     cmd = self._parse(msg)
  196.                     self.logPretty(cmd)
  197.                     self._handle(cmd)
  198.                     self._messages.append(cmd)
  199.                 self._buffer = self._buffer.split("\r\n")[-1]
  200.  
  201.     def _handle(self, cmd):
  202.         if cmd.command == "PING":
  203.             self._sendCommand("pong", trailing=cmd.trailing)
  204.  
  205.         elif cmd.command == "376":
  206.             self.joinFavorites()
  207.             self.joined = True
  208.  
  209.         elif not self.identified and cmd.nick.lower() == "nickserv":
  210.             self._sendCommand("privmsg", ["nickserv"], "IDENTIFY " + self.password)
  211.             self.identified = True
  212.  
  213.     def _parse(self, msg):
  214.         return IRCCommand(msg)
  215.  
  216.     def _sendCommand(self, command, params=[], trailing=""):
  217.         par = ""
  218.         for p in params:
  219.             if p.strip() != "": par += " " + p.strip()
  220.  
  221.         if trailing != "": trailing = " :" + trailing
  222.         cmd = command.upper() + par + trailing
  223.  
  224.         self.verboseOut("CLIENT: " + cmd)
  225.         self.sock.send((cmd + "\r\n").encode())
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement